convex 1.34.0 → 1.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +98 -43
- package/dist/browser.bundle.js +13 -10
- package/dist/browser.bundle.js.map +3 -3
- package/dist/cjs/browser/index-node.js +3 -1
- package/dist/cjs/browser/index.js +3 -1
- package/dist/cjs/browser/index.js.map +2 -2
- package/dist/cjs/browser/query_options.js.map +2 -2
- package/dist/cjs/browser/sync/authentication_manager.js +4 -1
- package/dist/cjs/browser/sync/authentication_manager.js.map +2 -2
- package/dist/cjs/browser/sync/web_socket_manager.js +1 -7
- package/dist/cjs/browser/sync/web_socket_manager.js.map +2 -2
- package/dist/cjs/cli/aiFiles.js +39 -20
- package/dist/cjs/cli/aiFiles.js.map +3 -3
- package/dist/cjs/cli/codegen_templates/readme.js +14 -1
- package/dist/cjs/cli/codegen_templates/readme.js.map +2 -2
- package/dist/cjs/cli/configure.js +34 -32
- package/dist/cjs/cli/configure.js.map +2 -2
- package/dist/cjs/cli/deploy.js +7 -8
- package/dist/cjs/cli/deploy.js.map +2 -2
- package/dist/cjs/cli/deploymentCreate.js +225 -40
- package/dist/cjs/cli/deploymentCreate.js.map +3 -3
- package/dist/cjs/cli/deploymentSelect.js +14 -13
- package/dist/cjs/cli/deploymentSelect.js.map +2 -2
- package/dist/cjs/cli/dev.js +30 -11
- package/dist/cjs/cli/dev.js.map +2 -2
- package/dist/cjs/cli/docs.js +1 -1
- package/dist/cjs/cli/docs.js.map +2 -2
- package/dist/cjs/cli/init.js +1 -1
- package/dist/cjs/cli/init.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/agentsmd.js +73 -0
- package/dist/cjs/cli/lib/aiFiles/agentsmd.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/claudemd.js +73 -0
- package/dist/cjs/cli/lib/aiFiles/claudemd.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/cursorrules.js +48 -0
- package/dist/cjs/cli/lib/aiFiles/cursorrules.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js +58 -0
- package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/index.js +215 -0
- package/dist/cjs/cli/lib/aiFiles/index.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/paths.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/skills.js +196 -0
- package/dist/cjs/cli/lib/aiFiles/skills.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/state.js +96 -0
- package/dist/cjs/cli/lib/aiFiles/state.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/status.js +198 -0
- package/dist/cjs/cli/lib/aiFiles/status.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/utils.js +128 -0
- package/dist/cjs/cli/lib/aiFiles/utils.js.map +7 -0
- package/dist/cjs/cli/lib/api.js +70 -7
- package/dist/cjs/cli/lib/api.js.map +2 -2
- package/dist/cjs/cli/lib/command.js +10 -6
- package/dist/cjs/cli/lib/command.js.map +2 -2
- package/dist/cjs/cli/lib/config.js +43 -7
- package/dist/cjs/cli/lib/config.js.map +3 -3
- package/dist/cjs/cli/lib/deploy2.js +9 -26
- package/dist/cjs/cli/lib/deploy2.js.map +2 -2
- package/dist/cjs/cli/lib/deployApi/componentDefinition.js +4 -1
- package/dist/cjs/cli/lib/deployApi/componentDefinition.js.map +2 -2
- package/dist/cjs/cli/lib/deploymentSelection.js +45 -2
- package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/cjs/cli/lib/deploymentSelector.js +1 -0
- package/dist/cjs/cli/lib/deploymentSelector.js.map +2 -2
- package/dist/cjs/cli/lib/dev.js +162 -117
- package/dist/cjs/cli/lib/dev.js.map +2 -2
- package/dist/cjs/cli/lib/env.js +1 -13
- package/dist/cjs/cli/lib/env.js.map +2 -2
- package/dist/cjs/cli/lib/expiration.js +104 -0
- package/dist/cjs/cli/lib/expiration.js.map +7 -0
- package/dist/cjs/cli/lib/generatedFunctionLogsApi.js.map +1 -1
- package/dist/cjs/cli/lib/init.js +4 -3
- package/dist/cjs/cli/lib/init.js.map +2 -2
- package/dist/cjs/cli/lib/insights.js +1 -1
- package/dist/cjs/cli/lib/insights.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/anonymous.js +15 -8
- package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/localDeployment.js +8 -10
- package/dist/cjs/cli/lib/localDeployment/localDeployment.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/run.js +1 -0
- package/dist/cjs/cli/lib/localDeployment/run.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/upgrade.js +2 -2
- package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/utils.js +9 -0
- package/dist/cjs/cli/lib/localDeployment/utils.js.map +2 -2
- package/dist/cjs/cli/lib/mcp/tools/status.js +1 -1
- package/dist/cjs/cli/lib/mcp/tools/status.js.map +2 -2
- package/dist/cjs/cli/lib/updates.js +12 -13
- package/dist/cjs/cli/lib/updates.js.map +2 -2
- package/dist/cjs/cli/lib/usage.js +2 -1
- package/dist/cjs/cli/lib/usage.js.map +2 -2
- package/dist/cjs/cli/lib/utils/prompts.js +2 -1
- package/dist/cjs/cli/lib/utils/prompts.js.map +2 -2
- package/dist/cjs/cli/lib/utils/utils.js +46 -20
- package/dist/cjs/cli/lib/utils/utils.js.map +3 -3
- package/dist/cjs/cli/lib/versionApi.js +7 -4
- package/dist/cjs/cli/lib/versionApi.js.map +2 -2
- package/dist/cjs/cli/lib/workos/workos.js +4 -6
- package/dist/cjs/cli/lib/workos/workos.js.map +2 -2
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react/client.js +43 -6
- package/dist/cjs/react/client.js.map +2 -2
- package/dist/cjs/react/index.js +2 -0
- package/dist/cjs/react/index.js.map +2 -2
- package/dist/cjs/react-clerk/ConvexProviderWithClerk.js.map +1 -1
- package/dist/cjs/server/api.js.map +2 -2
- package/dist/cjs/server/components/definition.js.map +1 -1
- package/dist/cjs/server/components/index.js +40 -4
- package/dist/cjs/server/components/index.js.map +2 -2
- package/dist/cjs/server/data_model.js.map +1 -1
- package/dist/cjs/server/impl/meta_impl.js +78 -0
- package/dist/cjs/server/impl/meta_impl.js.map +7 -0
- package/dist/cjs/server/impl/registration_impl.js +16 -11
- package/dist/cjs/server/impl/registration_impl.js.map +2 -2
- package/dist/cjs/server/index.js.map +2 -2
- package/dist/cjs/server/meta.js +17 -0
- package/dist/cjs/server/meta.js.map +7 -0
- package/dist/cjs/server/registration.js.map +1 -1
- package/dist/cjs-types/browser/index.d.ts +1 -0
- package/dist/cjs-types/browser/index.d.ts.map +1 -1
- package/dist/cjs-types/browser/query_options.d.ts +12 -9
- package/dist/cjs-types/browser/query_options.d.ts.map +1 -1
- package/dist/cjs-types/browser/sync/authentication_manager.d.ts.map +1 -1
- package/dist/cjs-types/browser/sync/web_socket_manager.d.ts.map +1 -1
- package/dist/cjs-types/cli/aiFiles.d.ts.map +1 -1
- package/dist/cjs-types/cli/codegen_templates/readme.d.ts.map +1 -1
- package/dist/cjs-types/cli/configure.d.ts.map +1 -1
- package/dist/cjs-types/cli/configure.test.d.ts +2 -0
- package/dist/cjs-types/cli/configure.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/deploy.d.ts.map +1 -1
- package/dist/cjs-types/cli/deploymentCreate.d.ts +1 -0
- package/dist/cjs-types/cli/deploymentCreate.d.ts.map +1 -1
- package/dist/cjs-types/cli/deploymentSelect.d.ts +2 -1
- package/dist/cjs-types/cli/deploymentSelect.d.ts.map +1 -1
- package/dist/cjs-types/cli/dev.d.ts +3 -1
- package/dist/cjs-types/cli/dev.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts +19 -0
- package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts +19 -0
- package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/cursorrules.d.ts +10 -0
- package/dist/cjs-types/cli/lib/aiFiles/cursorrules.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts +12 -0
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/index.d.ts +42 -0
- package/dist/cjs-types/cli/lib/aiFiles/index.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/index.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/integration.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/{ai → aiFiles}/paths.d.ts +4 -0
- package/dist/cjs-types/cli/lib/aiFiles/paths.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/prompt.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts +20 -0
- package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/state.d.ts +38 -0
- package/dist/cjs-types/cli/lib/aiFiles/state.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/status.d.ts +6 -0
- package/dist/cjs-types/cli/lib/aiFiles/status.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts +56 -0
- package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/api.d.ts +3 -3
- package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/command.d.ts +2 -1
- package/dist/cjs-types/cli/lib/command.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/config.d.ts +18 -6
- package/dist/cjs-types/cli/lib/config.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deploy2.d.ts +5 -2
- package/dist/cjs-types/cli/lib/deploy2.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts +27 -12
- package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deployApi/definitionConfig.d.ts +24 -24
- package/dist/cjs-types/cli/lib/deployApi/modules.d.ts +14 -14
- package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +61 -52
- package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deploymentSelector.d.ts +2 -0
- package/dist/cjs-types/cli/lib/deploymentSelector.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/env.d.ts +0 -4
- package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/expiration.d.ts +35 -0
- package/dist/cjs-types/cli/lib/expiration.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/expiration.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/expiration.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts +16 -1
- package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/init.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/run.d.ts +15 -0
- package/dist/cjs-types/cli/lib/localDeployment/run.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +7 -0
- package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/mcp/requestContext.d.ts +3 -3
- package/dist/cjs-types/cli/lib/mcp/tools/insights.d.ts +2 -2
- package/dist/cjs-types/cli/lib/updates.d.ts +4 -3
- package/dist/cjs-types/cli/lib/updates.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/usage.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/utils/prompts.d.ts +1 -0
- package/dist/cjs-types/cli/lib/utils/prompts.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/utils/utils.d.ts +16 -2
- package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/versionApi.d.ts +7 -1
- package/dist/cjs-types/cli/lib/versionApi.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/workos/workos.d.ts.map +1 -1
- package/dist/cjs-types/index.d.ts +1 -1
- package/dist/cjs-types/react/client.d.ts +54 -2
- package/dist/cjs-types/react/client.d.ts.map +1 -1
- package/dist/cjs-types/react/index.d.ts +7 -2
- package/dist/cjs-types/react/index.d.ts.map +1 -1
- package/dist/cjs-types/react/use_query_object_options.test.d.ts +5 -0
- package/dist/cjs-types/react/use_query_object_options.test.d.ts.map +1 -0
- package/dist/cjs-types/react/use_query_result.test.d.ts +5 -0
- package/dist/cjs-types/react/use_query_result.test.d.ts.map +1 -0
- package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -1
- package/dist/cjs-types/server/api.d.ts +5 -1
- package/dist/cjs-types/server/api.d.ts.map +1 -1
- package/dist/cjs-types/server/components/definition.d.ts +1 -0
- package/dist/cjs-types/server/components/definition.d.ts.map +1 -1
- package/dist/cjs-types/server/components/index.d.ts +5 -1
- package/dist/cjs-types/server/components/index.d.ts.map +1 -1
- package/dist/cjs-types/server/data_model.d.ts +2 -1
- package/dist/cjs-types/server/data_model.d.ts.map +1 -1
- package/dist/cjs-types/server/impl/meta_impl.d.ts +5 -0
- package/dist/cjs-types/server/impl/meta_impl.d.ts.map +1 -0
- package/dist/cjs-types/server/impl/registration_impl.d.ts.map +1 -1
- package/dist/cjs-types/server/index.d.ts +1 -0
- package/dist/cjs-types/server/index.d.ts.map +1 -1
- package/dist/cjs-types/server/meta.d.ts +72 -0
- package/dist/cjs-types/server/meta.d.ts.map +1 -0
- package/dist/cjs-types/server/registration.d.ts.map +1 -1
- package/dist/cli.bundle.cjs +2446 -1933
- package/dist/cli.bundle.cjs.map +4 -4
- package/dist/esm/browser/index-node.js +1 -0
- package/dist/esm/browser/index.js +1 -0
- package/dist/esm/browser/index.js.map +2 -2
- package/dist/esm/browser/query_options.js.map +2 -2
- package/dist/esm/browser/sync/authentication_manager.js +4 -1
- package/dist/esm/browser/sync/authentication_manager.js.map +2 -2
- package/dist/esm/browser/sync/web_socket_manager.js +1 -7
- package/dist/esm/browser/sync/web_socket_manager.js.map +2 -2
- package/dist/esm/cli/aiFiles.js +41 -23
- package/dist/esm/cli/aiFiles.js.map +2 -2
- package/dist/esm/cli/codegen_templates/readme.js +14 -1
- package/dist/esm/cli/codegen_templates/readme.js.map +2 -2
- package/dist/esm/cli/configure.js +35 -33
- package/dist/esm/cli/configure.js.map +2 -2
- package/dist/esm/cli/deploy.js +11 -10
- package/dist/esm/cli/deploy.js.map +2 -2
- package/dist/esm/cli/deploymentCreate.js +238 -42
- package/dist/esm/cli/deploymentCreate.js.map +2 -2
- package/dist/esm/cli/deploymentSelect.js +13 -12
- package/dist/esm/cli/deploymentSelect.js.map +2 -2
- package/dist/esm/cli/dev.js +34 -13
- package/dist/esm/cli/dev.js.map +2 -2
- package/dist/esm/cli/docs.js +1 -1
- package/dist/esm/cli/docs.js.map +2 -2
- package/dist/esm/cli/init.js +2 -2
- package/dist/esm/cli/init.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/agentsmd.js +56 -0
- package/dist/esm/cli/lib/aiFiles/agentsmd.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/claudemd.js +56 -0
- package/dist/esm/cli/lib/aiFiles/claudemd.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/cursorrules.js +16 -0
- package/dist/esm/cli/lib/aiFiles/cursorrules.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/guidelinesmd.js +35 -0
- package/dist/esm/cli/lib/aiFiles/guidelinesmd.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/index.js +193 -0
- package/dist/esm/cli/lib/aiFiles/index.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/paths.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/skills.js +163 -0
- package/dist/esm/cli/lib/aiFiles/skills.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/state.js +60 -0
- package/dist/esm/cli/lib/aiFiles/state.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/status.js +178 -0
- package/dist/esm/cli/lib/aiFiles/status.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/utils.js +97 -0
- package/dist/esm/cli/lib/aiFiles/utils.js.map +7 -0
- package/dist/esm/cli/lib/api.js +70 -7
- package/dist/esm/cli/lib/api.js.map +2 -2
- package/dist/esm/cli/lib/command.js +10 -6
- package/dist/esm/cli/lib/command.js.map +2 -2
- package/dist/esm/cli/lib/config.js +41 -6
- package/dist/esm/cli/lib/config.js.map +2 -2
- package/dist/esm/cli/lib/deploy2.js +13 -26
- package/dist/esm/cli/lib/deploy2.js.map +2 -2
- package/dist/esm/cli/lib/deployApi/componentDefinition.js +4 -1
- package/dist/esm/cli/lib/deployApi/componentDefinition.js.map +2 -2
- package/dist/esm/cli/lib/deploymentSelection.js +46 -2
- package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/esm/cli/lib/deploymentSelector.js +1 -0
- package/dist/esm/cli/lib/deploymentSelector.js.map +2 -2
- package/dist/esm/cli/lib/dev.js +162 -118
- package/dist/esm/cli/lib/dev.js.map +2 -2
- package/dist/esm/cli/lib/env.js +0 -11
- package/dist/esm/cli/lib/env.js.map +2 -2
- package/dist/esm/cli/lib/expiration.js +80 -0
- package/dist/esm/cli/lib/expiration.js.map +7 -0
- package/dist/esm/cli/lib/init.js +4 -3
- package/dist/esm/cli/lib/init.js.map +2 -2
- package/dist/esm/cli/lib/insights.js +1 -1
- package/dist/esm/cli/lib/insights.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/anonymous.js +16 -9
- package/dist/esm/cli/lib/localDeployment/anonymous.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/localDeployment.js +9 -11
- package/dist/esm/cli/lib/localDeployment/localDeployment.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/run.js +1 -1
- package/dist/esm/cli/lib/localDeployment/run.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/upgrade.js +2 -2
- package/dist/esm/cli/lib/localDeployment/upgrade.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/utils.js +8 -0
- package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
- package/dist/esm/cli/lib/mcp/tools/status.js +1 -1
- package/dist/esm/cli/lib/mcp/tools/status.js.map +2 -2
- package/dist/esm/cli/lib/updates.js +14 -12
- package/dist/esm/cli/lib/updates.js.map +2 -2
- package/dist/esm/cli/lib/usage.js +2 -1
- package/dist/esm/cli/lib/usage.js.map +2 -2
- package/dist/esm/cli/lib/utils/prompts.js +2 -1
- package/dist/esm/cli/lib/utils/prompts.js.map +2 -2
- package/dist/esm/cli/lib/utils/utils.js +45 -20
- package/dist/esm/cli/lib/utils/utils.js.map +3 -3
- package/dist/esm/cli/lib/versionApi.js +7 -4
- package/dist/esm/cli/lib/versionApi.js.map +2 -2
- package/dist/esm/cli/lib/workos/workos.js +4 -6
- package/dist/esm/cli/lib/workos/workos.js.map +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/client.js +43 -6
- package/dist/esm/react/client.js.map +2 -2
- package/dist/esm/react/index.js +1 -0
- package/dist/esm/react/index.js.map +2 -2
- package/dist/esm/react-clerk/ConvexProviderWithClerk.js.map +1 -1
- package/dist/esm/server/api.js.map +2 -2
- package/dist/esm/server/components/index.js +40 -4
- package/dist/esm/server/components/index.js.map +2 -2
- package/dist/esm/server/impl/meta_impl.js +54 -0
- package/dist/esm/server/impl/meta_impl.js.map +7 -0
- package/dist/esm/server/impl/registration_impl.js +20 -11
- package/dist/esm/server/impl/registration_impl.js.map +2 -2
- package/dist/esm/server/index.js.map +2 -2
- package/dist/esm/server/meta.js +2 -0
- package/dist/esm/server/meta.js.map +7 -0
- package/dist/esm-types/browser/index.d.ts +1 -0
- package/dist/esm-types/browser/index.d.ts.map +1 -1
- package/dist/esm-types/browser/query_options.d.ts +12 -9
- package/dist/esm-types/browser/query_options.d.ts.map +1 -1
- package/dist/esm-types/browser/sync/authentication_manager.d.ts.map +1 -1
- package/dist/esm-types/browser/sync/web_socket_manager.d.ts.map +1 -1
- package/dist/esm-types/cli/aiFiles.d.ts.map +1 -1
- package/dist/esm-types/cli/codegen_templates/readme.d.ts.map +1 -1
- package/dist/esm-types/cli/configure.d.ts.map +1 -1
- package/dist/esm-types/cli/configure.test.d.ts +2 -0
- package/dist/esm-types/cli/configure.test.d.ts.map +1 -0
- package/dist/esm-types/cli/deploy.d.ts.map +1 -1
- package/dist/esm-types/cli/deploymentCreate.d.ts +1 -0
- package/dist/esm-types/cli/deploymentCreate.d.ts.map +1 -1
- package/dist/esm-types/cli/deploymentSelect.d.ts +2 -1
- package/dist/esm-types/cli/deploymentSelect.d.ts.map +1 -1
- package/dist/esm-types/cli/dev.d.ts +3 -1
- package/dist/esm-types/cli/dev.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts +19 -0
- package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts +19 -0
- package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/cursorrules.d.ts +10 -0
- package/dist/esm-types/cli/lib/aiFiles/cursorrules.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts +12 -0
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/index.d.ts +42 -0
- package/dist/esm-types/cli/lib/aiFiles/index.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/index.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/integration.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/{ai → aiFiles}/paths.d.ts +4 -0
- package/dist/esm-types/cli/lib/aiFiles/paths.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/prompt.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/skills.d.ts +20 -0
- package/dist/esm-types/cli/lib/aiFiles/skills.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/state.d.ts +38 -0
- package/dist/esm-types/cli/lib/aiFiles/state.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/status.d.ts +6 -0
- package/dist/esm-types/cli/lib/aiFiles/status.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/utils.d.ts +56 -0
- package/dist/esm-types/cli/lib/aiFiles/utils.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/api.d.ts +3 -3
- package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/command.d.ts +2 -1
- package/dist/esm-types/cli/lib/command.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/config.d.ts +18 -6
- package/dist/esm-types/cli/lib/config.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deploy2.d.ts +5 -2
- package/dist/esm-types/cli/lib/deploy2.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts +27 -12
- package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deployApi/definitionConfig.d.ts +24 -24
- package/dist/esm-types/cli/lib/deployApi/modules.d.ts +14 -14
- package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +61 -52
- package/dist/esm-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deploymentSelector.d.ts +2 -0
- package/dist/esm-types/cli/lib/deploymentSelector.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/env.d.ts +0 -4
- package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/expiration.d.ts +35 -0
- package/dist/esm-types/cli/lib/expiration.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/expiration.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/expiration.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts +16 -1
- package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/init.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/run.d.ts +15 -0
- package/dist/esm-types/cli/lib/localDeployment/run.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +7 -0
- package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/mcp/requestContext.d.ts +3 -3
- package/dist/esm-types/cli/lib/mcp/tools/insights.d.ts +2 -2
- package/dist/esm-types/cli/lib/updates.d.ts +4 -3
- package/dist/esm-types/cli/lib/updates.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/usage.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/utils/prompts.d.ts +1 -0
- package/dist/esm-types/cli/lib/utils/prompts.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/utils/utils.d.ts +16 -2
- package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/versionApi.d.ts +7 -1
- package/dist/esm-types/cli/lib/versionApi.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/workos/workos.d.ts.map +1 -1
- package/dist/esm-types/index.d.ts +1 -1
- package/dist/esm-types/react/client.d.ts +54 -2
- package/dist/esm-types/react/client.d.ts.map +1 -1
- package/dist/esm-types/react/index.d.ts +7 -2
- package/dist/esm-types/react/index.d.ts.map +1 -1
- package/dist/esm-types/react/use_query_object_options.test.d.ts +5 -0
- package/dist/esm-types/react/use_query_object_options.test.d.ts.map +1 -0
- package/dist/esm-types/react/use_query_result.test.d.ts +5 -0
- package/dist/esm-types/react/use_query_result.test.d.ts.map +1 -0
- package/dist/esm-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -1
- package/dist/esm-types/server/api.d.ts +5 -1
- package/dist/esm-types/server/api.d.ts.map +1 -1
- package/dist/esm-types/server/components/definition.d.ts +1 -0
- package/dist/esm-types/server/components/definition.d.ts.map +1 -1
- package/dist/esm-types/server/components/index.d.ts +5 -1
- package/dist/esm-types/server/components/index.d.ts.map +1 -1
- package/dist/esm-types/server/data_model.d.ts +2 -1
- package/dist/esm-types/server/data_model.d.ts.map +1 -1
- package/dist/esm-types/server/impl/meta_impl.d.ts +5 -0
- package/dist/esm-types/server/impl/meta_impl.d.ts.map +1 -0
- package/dist/esm-types/server/impl/registration_impl.d.ts.map +1 -1
- package/dist/esm-types/server/index.d.ts +1 -0
- package/dist/esm-types/server/index.d.ts.map +1 -1
- package/dist/esm-types/server/meta.d.ts +72 -0
- package/dist/esm-types/server/meta.d.ts.map +1 -0
- package/dist/esm-types/server/registration.d.ts.map +1 -1
- package/dist/react.bundle.js +55 -15
- package/dist/react.bundle.js.map +3 -3
- package/package.json +11 -7
- package/schemas/convex.schema.json +22 -3
- package/src/browser/index.ts +3 -0
- package/src/browser/query_options.test.ts +0 -9
- package/src/browser/query_options.ts +36 -15
- package/src/browser/sync/authentication_manager.ts +9 -4
- package/src/browser/sync/client_node.test.ts +125 -0
- package/src/browser/sync/web_socket_manager.ts +1 -7
- package/src/cli/aiFiles.ts +56 -33
- package/src/cli/codegen_templates/readme.ts +14 -1
- package/src/cli/configure.test.ts +138 -0
- package/src/cli/configure.ts +62 -55
- package/src/cli/deploy.ts +12 -9
- package/src/cli/deploymentCreate.test.ts +349 -14
- package/src/cli/deploymentCreate.ts +268 -41
- package/src/cli/deploymentSelect.test.ts +136 -27
- package/src/cli/deploymentSelect.ts +50 -41
- package/src/cli/deploymentSelection.test.ts +399 -37
- package/src/cli/dev.ts +49 -14
- package/src/cli/docs.ts +1 -1
- package/src/cli/init.ts +2 -2
- package/src/cli/lib/{ai → aiFiles}/MANUAL_TESTING.md +6 -2
- package/src/cli/lib/aiFiles/agentsmd.test.ts +133 -0
- package/src/cli/lib/aiFiles/agentsmd.ts +81 -0
- package/src/cli/lib/aiFiles/claudemd.test.ts +92 -0
- package/src/cli/lib/aiFiles/claudemd.ts +81 -0
- package/src/cli/lib/aiFiles/cursorrules.ts +25 -0
- package/src/cli/lib/aiFiles/guidelinesmd.test.ts +50 -0
- package/src/cli/lib/aiFiles/guidelinesmd.ts +49 -0
- package/src/cli/lib/{ai → aiFiles}/index.test.ts +343 -516
- package/src/cli/lib/aiFiles/index.ts +297 -0
- package/src/cli/lib/{ai → aiFiles}/integration.test.ts +195 -158
- package/src/cli/lib/{ai → aiFiles}/paths.ts +5 -0
- package/src/cli/lib/{ai → aiFiles}/prompt.test.ts +79 -31
- package/src/cli/lib/aiFiles/skills.ts +243 -0
- package/src/cli/lib/aiFiles/state.test.ts +280 -0
- package/src/cli/lib/aiFiles/state.ts +82 -0
- package/src/cli/lib/aiFiles/status.ts +246 -0
- package/src/cli/lib/aiFiles/utils.test.ts +50 -0
- package/src/cli/lib/aiFiles/utils.ts +191 -0
- package/src/cli/lib/api.ts +88 -7
- package/src/cli/lib/command.ts +18 -8
- package/src/cli/lib/config.test.ts +185 -8
- package/src/cli/lib/config.ts +73 -12
- package/src/cli/lib/deploy2.ts +14 -27
- package/src/cli/lib/deployApi/componentDefinition.ts +4 -1
- package/src/cli/lib/deploymentSelection.ts +59 -6
- package/src/cli/lib/deploymentSelector.test.ts +6 -0
- package/src/cli/lib/deploymentSelector.ts +2 -0
- package/src/cli/lib/dev.ts +202 -153
- package/src/cli/lib/env.ts +0 -15
- package/src/cli/lib/expiration.test.ts +159 -0
- package/src/cli/lib/expiration.ts +124 -0
- package/src/cli/lib/generatedFunctionLogsApi.ts +16 -1
- package/src/cli/lib/init.ts +6 -2
- package/src/cli/lib/insights.ts +1 -1
- package/src/cli/lib/localDeployment/anonymous.ts +19 -9
- package/src/cli/lib/localDeployment/localDeployment.ts +9 -11
- package/src/cli/lib/localDeployment/run.ts +1 -1
- package/src/cli/lib/localDeployment/upgrade.ts +12 -10
- package/src/cli/lib/localDeployment/utils.ts +12 -0
- package/src/cli/lib/mcp/tools/status.ts +1 -1
- package/src/cli/lib/updates.test.ts +97 -60
- package/src/cli/lib/updates.ts +17 -15
- package/src/cli/lib/usage.ts +3 -1
- package/src/cli/lib/utils/prompts.ts +2 -0
- package/src/cli/lib/utils/utils.test.ts +6 -6
- package/src/cli/lib/utils/utils.ts +66 -27
- package/src/cli/lib/versionApi.test.ts +13 -10
- package/src/cli/lib/versionApi.ts +13 -5
- package/src/cli/lib/workos/workos.ts +4 -5
- package/src/index.ts +1 -1
- package/src/react/client.test.tsx +65 -0
- package/src/react/client.ts +129 -13
- package/src/react/index.ts +9 -1
- package/src/react/use_query_object_options.test.ts +50 -0
- package/src/react/use_query_result.test.ts +41 -0
- package/src/react-clerk/ConvexProviderWithClerk.test.tsx +1 -1
- package/src/react-clerk/ConvexProviderWithClerk.tsx +1 -1
- package/src/server/api.ts +5 -1
- package/src/server/components/definition.ts +3 -0
- package/src/server/components/index.ts +62 -5
- package/src/server/data_model.ts +2 -1
- package/src/server/impl/meta_impl.ts +74 -0
- package/src/server/impl/registration_impl.ts +21 -9
- package/src/server/index.ts +8 -0
- package/src/server/meta.ts +76 -0
- package/src/server/registration.ts +10 -0
- package/src/server/schema.test.ts +78 -1
- package/dist/cjs/cli/lib/ai/config.js +0 -144
- package/dist/cjs/cli/lib/ai/config.js.map +0 -7
- package/dist/cjs/cli/lib/ai/index.js +0 -704
- package/dist/cjs/cli/lib/ai/index.js.map +0 -7
- package/dist/cjs/cli/lib/ai/paths.js.map +0 -7
- package/dist/cjs-types/cli/lib/ai/config.d.ts +0 -50
- package/dist/cjs-types/cli/lib/ai/config.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/config.test.d.ts +0 -2
- package/dist/cjs-types/cli/lib/ai/config.test.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/index.d.ts +0 -56
- package/dist/cjs-types/cli/lib/ai/index.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/index.test.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/integration.test.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/paths.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/prompt.test.d.ts.map +0 -1
- package/dist/esm/cli/lib/ai/config.js +0 -109
- package/dist/esm/cli/lib/ai/config.js.map +0 -7
- package/dist/esm/cli/lib/ai/index.js +0 -684
- package/dist/esm/cli/lib/ai/index.js.map +0 -7
- package/dist/esm/cli/lib/ai/paths.js.map +0 -7
- package/dist/esm-types/cli/lib/ai/config.d.ts +0 -50
- package/dist/esm-types/cli/lib/ai/config.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/config.test.d.ts +0 -2
- package/dist/esm-types/cli/lib/ai/config.test.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/index.d.ts +0 -56
- package/dist/esm-types/cli/lib/ai/index.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/index.test.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/integration.test.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/paths.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/prompt.test.d.ts.map +0 -1
- package/src/cli/lib/ai/config.test.ts +0 -338
- package/src/cli/lib/ai/config.ts +0 -159
- package/src/cli/lib/ai/index.ts +0 -1006
- /package/dist/cjs/cli/lib/{ai → aiFiles}/paths.js +0 -0
- /package/dist/cjs-types/cli/lib/{ai → aiFiles}/index.test.d.ts +0 -0
- /package/dist/cjs-types/cli/lib/{ai → aiFiles}/integration.test.d.ts +0 -0
- /package/dist/cjs-types/cli/lib/{ai → aiFiles}/prompt.test.d.ts +0 -0
- /package/dist/esm/cli/lib/{ai → aiFiles}/paths.js +0 -0
- /package/dist/esm-types/cli/lib/{ai → aiFiles}/index.test.d.ts +0 -0
- /package/dist/esm-types/cli/lib/{ai → aiFiles}/integration.test.d.ts +0 -0
- /package/dist/esm-types/cli/lib/{ai → aiFiles}/prompt.test.d.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../browser-bundle.js", "../src/index.ts", "../src/values/base64.ts", "../src/common/index.ts", "../src/values/value.ts", "../src/values/errors.ts", "../src/browser/logging.ts", "../src/browser/sync/udf_path_utils.ts", "../src/browser/sync/local_state.ts", "../src/browser/sync/request_manager.ts", "../src/server/functionName.ts", "../src/server/components/paths.ts", "../src/server/api.ts", "../src/browser/sync/optimistic_updates_impl.ts", "../src/vendor/long.ts", "../src/browser/sync/remote_query_set.ts", "../src/browser/sync/protocol.ts", "../src/browser/sync/web_socket_manager.ts", "../src/browser/sync/session.ts", "../src/vendor/jwt-decode/index.ts", "../src/browser/sync/authentication_manager.ts", "../src/browser/sync/metrics.ts", "../src/browser/sync/client.ts", "../src/browser/sync/pagination.ts", "../src/browser/sync/paginated_query_client.ts", "../src/browser/simple_client.ts", "../src/browser/http_client.ts"],
|
|
4
|
-
"sourcesContent": ["// Code exposed in the browser bundle\n\nexport * from \"./src/browser/index.js\";\nexport { anyApi } from \"./src/server/index.js\";\n", "export const version = \"1.34.0\";\n", "/*\nhttps://github.com/beatgammit/base64-js/blob/88957c9943c7e2a0f03cdf73e71d579e433627d3/index.js\nCopyright (c) 2014 Jameson Little\nThe MIT License (MIT)\n*/\n\n// Vendored because this library has no ESM build, and some environments\n// (SvelteKit) are happiest when all dependencies are ESM.\n\nvar lookup: string[] = [];\nvar revLookup: number[] = [];\nvar Arr = Uint8Array;\n\nvar code = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i];\n revLookup[code.charCodeAt(i)] = i;\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup[\"-\".charCodeAt(0)] = 62;\nrevLookup[\"_\".charCodeAt(0)] = 63;\n\nfunction getLens(b64: string) {\n var len = b64.length;\n\n if (len % 4 > 0) {\n throw new Error(\"Invalid string. Length must be a multiple of 4\");\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf(\"=\");\n if (validLen === -1) validLen = len;\n\n var placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4);\n\n return [validLen, placeHoldersLen];\n}\n\n// base64 is 4/3 + up to two characters of the original data\n/** @public */\nexport function byteLength(b64: string): number {\n var lens = getLens(b64);\n var validLen = lens[0];\n var placeHoldersLen = lens[1];\n return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;\n}\n\nfunction _byteLength(_b64: string, validLen: number, placeHoldersLen: number) {\n return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;\n}\n\n/** @public */\nexport function toByteArray(b64: string): Uint8Array {\n var tmp;\n var lens = getLens(b64);\n var validLen = lens[0];\n var placeHoldersLen = lens[1];\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));\n\n var curByte = 0;\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0 ? validLen - 4 : validLen;\n\n var i;\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)];\n arr[curByte++] = (tmp >> 16) & 0xff;\n arr[curByte++] = (tmp >> 8) & 0xff;\n arr[curByte++] = tmp & 0xff;\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4);\n arr[curByte++] = tmp & 0xff;\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2);\n arr[curByte++] = (tmp >> 8) & 0xff;\n arr[curByte++] = tmp & 0xff;\n }\n\n return arr;\n}\n\nfunction tripletToBase64(num: number) {\n return (\n lookup[(num >> 18) & 0x3f] +\n lookup[(num >> 12) & 0x3f] +\n lookup[(num >> 6) & 0x3f] +\n lookup[num & 0x3f]\n );\n}\n\nfunction encodeChunk(uint8: Uint8Array, start: number, end: number) {\n var tmp;\n var output = [];\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xff0000) +\n ((uint8[i + 1] << 8) & 0xff00) +\n (uint8[i + 2] & 0xff);\n output.push(tripletToBase64(tmp));\n }\n return output.join(\"\");\n}\n\n/** @public */\nexport function fromByteArray(uint8: Uint8Array): string {\n var tmp;\n var len = uint8.length;\n var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes\n var parts = [];\n var maxChunkLength = 16383; // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(\n encodeChunk(\n uint8,\n i,\n i + maxChunkLength > len2 ? len2 : i + maxChunkLength,\n ),\n );\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1];\n parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + \"==\");\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1];\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3f] +\n lookup[(tmp << 2) & 0x3f] +\n \"=\",\n );\n }\n\n return parts.join(\"\");\n}\n\nexport function fromByteArrayUrlSafeNoPadding(uint8: Uint8Array): string {\n return fromByteArray(uint8)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n}\n", "import type { Value } from \"../values/value.js\";\n\n/**\n * Validate that the arguments to a Convex function are an object, defaulting\n * `undefined` to `{}`.\n */\nexport function parseArgs(\n args: Record<string, Value> | undefined,\n): Record<string, Value> {\n if (args === undefined) {\n return {};\n }\n if (!isSimpleObject(args)) {\n throw new Error(\n `The arguments to a Convex function must be an object. Received: ${\n args as any\n }`,\n );\n }\n return args;\n}\n\nexport function validateDeploymentUrl(deploymentUrl: string) {\n // Don't use things like `new URL(deploymentUrl).hostname` since these aren't\n // supported by React Native's JS environment\n if (typeof deploymentUrl === \"undefined\") {\n throw new Error(\n `Client created with undefined deployment address. If you used an environment variable, check that it's set.`,\n );\n }\n if (typeof deploymentUrl !== \"string\") {\n throw new Error(\n `Invalid deployment address: found ${deploymentUrl as any}\".`,\n );\n }\n if (\n !(deploymentUrl.startsWith(\"http:\") || deploymentUrl.startsWith(\"https:\"))\n ) {\n throw new Error(\n `Invalid deployment address: Must start with \"https://\" or \"http://\". Found \"${deploymentUrl}\".`,\n );\n }\n\n // Most clients should connect to \".convex.cloud\". But we also support localhost and\n // custom custom. We validate the deployment url is a valid url, which is the most\n // common failure pattern.\n try {\n new URL(deploymentUrl);\n } catch {\n throw new Error(\n `Invalid deployment address: \"${deploymentUrl}\" is not a valid URL. If you believe this URL is correct, use the \\`skipConvexDeploymentUrlCheck\\` option to bypass this.`,\n );\n }\n\n // If a user uses .convex.site, this is very likely incorrect.\n if (deploymentUrl.endsWith(\".convex.site\")) {\n throw new Error(\n `Invalid deployment address: \"${deploymentUrl}\" ends with .convex.site, which is used for HTTP Actions. Convex deployment URLs typically end with .convex.cloud? If you believe this URL is correct, use the \\`skipConvexDeploymentUrlCheck\\` option to bypass this.`,\n );\n }\n}\n\n/**\n * Check whether a value is a plain old JavaScript object.\n */\nexport function isSimpleObject(value: unknown) {\n const isObject = typeof value === \"object\";\n const prototype = Object.getPrototypeOf(value);\n const isSimple =\n prototype === null ||\n prototype === Object.prototype ||\n // Objects generated from other contexts (e.g. across Node.js `vm` modules) will not satisfy the previous\n // conditions but are still simple objects.\n prototype?.constructor?.name === \"Object\";\n return isObject && isSimple;\n}\n", "/**\n * Utilities for working with values stored in Convex.\n *\n * You can see the full set of supported types at\n * [Types](https://docs.convex.dev/using/types).\n * @module\n */\nimport * as Base64 from \"./base64.js\";\nimport { isSimpleObject } from \"../common/index.js\";\n\nconst LITTLE_ENDIAN = true;\n// This code is used by code that may not have bigint literals.\nconst MIN_INT64 = BigInt(\"-9223372036854775808\");\nconst MAX_INT64 = BigInt(\"9223372036854775807\");\nconst ZERO = BigInt(\"0\");\nconst EIGHT = BigInt(\"8\");\nconst TWOFIFTYSIX = BigInt(\"256\");\n\n/**\n * The type of JavaScript values serializable to JSON.\n *\n * @public\n */\nexport type JSONValue =\n | null\n | boolean\n | number\n | string\n | JSONValue[]\n | { [key: string]: JSONValue };\n\n/**\n * An identifier for a document in Convex.\n *\n * Convex documents are uniquely identified by their `Id`, which is accessible\n * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/database/document-ids).\n *\n * Documents can be loaded using `db.get(tableName, id)` in query and mutation functions.\n *\n * IDs are base 32 encoded strings which are URL safe.\n *\n * IDs are just strings at runtime, but this type can be used to distinguish them from other\n * strings at compile time.\n *\n * If you're using code generation, use the `Id` type generated for your data model in\n * `convex/_generated/dataModel.d.ts`.\n *\n * @typeParam TableName - A string literal type of the table name (like \"users\").\n *\n * @public\n */\nexport type Id<TableName extends string> = string & { __tableName: TableName };\n\n/**\n * A value supported by Convex.\n *\n * Values can be:\n * - stored inside of documents.\n * - used as arguments and return types to queries and mutation functions.\n *\n * You can see the full set of supported types at\n * [Types](https://docs.convex.dev/using/types).\n *\n * @public\n */\nexport type Value =\n | null\n | bigint\n | number\n | boolean\n | string\n | ArrayBuffer\n | Value[]\n | { [key: string]: undefined | Value };\n\n/**\n * The types of {@link Value} that can be used to represent numbers.\n *\n * @public\n */\nexport type NumericValue = bigint | number;\n\nfunction isSpecial(n: number) {\n return Number.isNaN(n) || !Number.isFinite(n) || Object.is(n, -0);\n}\n\nexport function slowBigIntToBase64(value: bigint): string {\n // the conversion is easy if we pretend it's unsigned\n if (value < ZERO) {\n value -= MIN_INT64 + MIN_INT64;\n }\n let hex = value.toString(16);\n if (hex.length % 2 === 1) hex = \"0\" + hex;\n\n const bytes = new Uint8Array(new ArrayBuffer(8));\n let i = 0;\n for (const hexByte of hex.match(/.{2}/g)!.reverse()) {\n bytes.set([parseInt(hexByte, 16)], i++);\n value >>= EIGHT;\n }\n return Base64.fromByteArray(bytes);\n}\n\nexport function slowBase64ToBigInt(encoded: string): bigint {\n const integerBytes = Base64.toByteArray(encoded);\n if (integerBytes.byteLength !== 8) {\n throw new Error(\n `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`,\n );\n }\n let value = ZERO;\n let power = ZERO;\n for (const byte of integerBytes) {\n value += BigInt(byte) * TWOFIFTYSIX ** power;\n power++;\n }\n if (value > MAX_INT64) {\n value += MIN_INT64 + MIN_INT64;\n }\n return value;\n}\n\nexport function modernBigIntToBase64(value: bigint): string {\n if (value < MIN_INT64 || MAX_INT64 < value) {\n throw new Error(\n `BigInt ${value} does not fit into a 64-bit signed integer.`,\n );\n }\n const buffer = new ArrayBuffer(8);\n new DataView(buffer).setBigInt64(0, value, true);\n return Base64.fromByteArray(new Uint8Array(buffer));\n}\n\nexport function modernBase64ToBigInt(encoded: string): bigint {\n const integerBytes = Base64.toByteArray(encoded);\n if (integerBytes.byteLength !== 8) {\n throw new Error(\n `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`,\n );\n }\n const intBytesView = new DataView(integerBytes.buffer);\n return intBytesView.getBigInt64(0, true);\n}\n\n// Fall back to a slower version on Safari 14 which lacks these APIs.\nexport const bigIntToBase64 = (DataView.prototype as any).setBigInt64\n ? modernBigIntToBase64\n : slowBigIntToBase64;\nexport const base64ToBigInt = (DataView.prototype as any).getBigInt64\n ? modernBase64ToBigInt\n : slowBase64ToBigInt;\n\nconst MAX_IDENTIFIER_LEN = 1024;\n\nfunction validateObjectField(k: string) {\n if (k.length > MAX_IDENTIFIER_LEN) {\n throw new Error(\n `Field name ${k} exceeds maximum field name length ${MAX_IDENTIFIER_LEN}.`,\n );\n }\n if (k.startsWith(\"$\")) {\n throw new Error(`Field name ${k} starts with a '$', which is reserved.`);\n }\n for (let i = 0; i < k.length; i += 1) {\n const charCode = k.charCodeAt(i);\n // Non-control ASCII characters\n if (charCode < 32 || charCode >= 127) {\n throw new Error(\n `Field name ${k} has invalid character '${k[i]}': Field names can only contain non-control ASCII characters`,\n );\n }\n }\n}\n\n/**\n * Parse a Convex value from its JSON representation.\n *\n * This function will deserialize serialized Int64s to `BigInt`s, Bytes to `ArrayBuffer`s etc.\n *\n * To learn more about Convex values, see [Types](https://docs.convex.dev/using/types).\n *\n * @param value - The JSON representation of a Convex value previously created with {@link convexToJson}.\n * @returns The JavaScript representation of the Convex value.\n *\n * @public\n */\nexport function jsonToConvex(value: JSONValue): Value {\n if (value === null) {\n return value;\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((value) => jsonToConvex(value));\n }\n if (typeof value !== \"object\") {\n throw new Error(`Unexpected type of ${value as any}`);\n }\n const entries = Object.entries(value);\n if (entries.length === 1) {\n const key = entries[0][0];\n if (key === \"$bytes\") {\n if (typeof value.$bytes !== \"string\") {\n throw new Error(`Malformed $bytes field on ${value as any}`);\n }\n return Base64.toByteArray(value.$bytes).buffer;\n }\n if (key === \"$integer\") {\n if (typeof value.$integer !== \"string\") {\n throw new Error(`Malformed $integer field on ${value as any}`);\n }\n return base64ToBigInt(value.$integer);\n }\n if (key === \"$float\") {\n if (typeof value.$float !== \"string\") {\n throw new Error(`Malformed $float field on ${value as any}`);\n }\n const floatBytes = Base64.toByteArray(value.$float);\n if (floatBytes.byteLength !== 8) {\n throw new Error(\n `Received ${floatBytes.byteLength} bytes, expected 8 for $float`,\n );\n }\n const floatBytesView = new DataView(floatBytes.buffer);\n const float = floatBytesView.getFloat64(0, LITTLE_ENDIAN);\n if (!isSpecial(float)) {\n throw new Error(`Float ${float} should be encoded as a number`);\n }\n return float;\n }\n if (key === \"$set\") {\n throw new Error(\n `Received a Set which is no longer supported as a Convex type.`,\n );\n }\n if (key === \"$map\") {\n throw new Error(\n `Received a Map which is no longer supported as a Convex type.`,\n );\n }\n }\n const out: { [key: string]: Value } = {};\n for (const [k, v] of Object.entries(value)) {\n validateObjectField(k);\n out[k] = jsonToConvex(v);\n }\n return out;\n}\n\nconst MAX_VALUE_FOR_ERROR_LEN = 16384;\n\nexport function stringifyValueForError(value: any) {\n const str = JSON.stringify(value, (_key, value) => {\n if (value === undefined) {\n // By default `JSON.stringify` converts undefined, functions, symbols,\n // Infinity, and NaN to null which produces a confusing error message.\n // We deal with `undefined` specifically because it's the most common.\n // Ideally we'd use a pretty-printing library that prints `undefined`\n // (no quotes), but it might not be worth the bundle size cost.\n return \"undefined\";\n }\n if (typeof value === \"bigint\") {\n // `JSON.stringify` throws on bigints by default.\n return `${value.toString()}n`;\n }\n return value;\n });\n if (str.length > MAX_VALUE_FOR_ERROR_LEN) {\n const rest = \"[...truncated]\";\n let truncateAt = MAX_VALUE_FOR_ERROR_LEN - rest.length;\n const codePoint = str.codePointAt(truncateAt - 1);\n if (codePoint !== undefined && codePoint > 0xffff) {\n // don't split a surrogate pair in half\n truncateAt -= 1;\n }\n return str.substring(0, truncateAt) + rest;\n }\n return str;\n}\n\nfunction convexToJsonInternal(\n value: Value,\n originalValue: Value,\n context: string,\n includeTopLevelUndefined: boolean,\n): JSONValue {\n if (value === undefined) {\n const contextText =\n context &&\n ` (present at path ${context} in original object ${stringifyValueForError(\n originalValue,\n )})`;\n throw new Error(\n `undefined is not a valid Convex value${contextText}. To learn about Convex's supported types, see https://docs.convex.dev/using/types.`,\n );\n }\n if (value === null) {\n return value;\n }\n if (typeof value === \"bigint\") {\n if (value < MIN_INT64 || MAX_INT64 < value) {\n throw new Error(\n `BigInt ${value} does not fit into a 64-bit signed integer.`,\n );\n }\n return { $integer: bigIntToBase64(value) };\n }\n if (typeof value === \"number\") {\n if (isSpecial(value)) {\n const buffer = new ArrayBuffer(8);\n new DataView(buffer).setFloat64(0, value, LITTLE_ENDIAN);\n return { $float: Base64.fromByteArray(new Uint8Array(buffer)) };\n } else {\n return value;\n }\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (value instanceof ArrayBuffer) {\n return { $bytes: Base64.fromByteArray(new Uint8Array(value)) };\n }\n if (Array.isArray(value)) {\n return value.map((value, i) =>\n convexToJsonInternal(value, originalValue, context + `[${i}]`, false),\n );\n }\n if (value instanceof Set) {\n throw new Error(\n errorMessageForUnsupportedType(context, \"Set\", [...value], originalValue),\n );\n }\n if (value instanceof Map) {\n throw new Error(\n errorMessageForUnsupportedType(context, \"Map\", [...value], originalValue),\n );\n }\n\n if (!isSimpleObject(value)) {\n const theType = value?.constructor?.name;\n const typeName = theType ? `${theType} ` : \"\";\n throw new Error(\n errorMessageForUnsupportedType(context, typeName, value, originalValue),\n );\n }\n\n const out: { [key: string]: JSONValue } = {};\n const entries = Object.entries(value);\n entries.sort(([k1, _v1], [k2, _v2]) => (k1 === k2 ? 0 : k1 < k2 ? -1 : 1));\n for (const [k, v] of entries) {\n if (v !== undefined) {\n validateObjectField(k);\n out[k] = convexToJsonInternal(v, originalValue, context + `.${k}`, false);\n } else if (includeTopLevelUndefined) {\n validateObjectField(k);\n out[k] = convexOrUndefinedToJsonInternal(\n v,\n originalValue,\n context + `.${k}`,\n );\n }\n }\n return out;\n}\n\nfunction errorMessageForUnsupportedType(\n context: string,\n typeName: string,\n value: any,\n originalValue: any,\n) {\n if (context) {\n return `${typeName}${stringifyValueForError(\n value,\n )} is not a supported Convex type (present at path ${context} in original object ${stringifyValueForError(\n originalValue,\n )}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.`;\n } else {\n return `${typeName}${stringifyValueForError(\n value,\n )} is not a supported Convex type.`;\n }\n}\n\n// convexOrUndefinedToJsonInternal wrapper exists so we can pipe through the\n// `originalValue` and `context` through for better error messaging.\nfunction convexOrUndefinedToJsonInternal(\n value: Value | undefined,\n originalValue: Value | undefined,\n context: string,\n): JSONValue {\n if (value === undefined) {\n return { $undefined: null };\n } else {\n if (originalValue === undefined) {\n // This should not happen.\n throw new Error(\n `Programming error. Current value is ${stringifyValueForError(\n value,\n )} but original value is undefined`,\n );\n }\n return convexToJsonInternal(value, originalValue, context, false);\n }\n}\n\n/**\n * Convert a Convex value to its JSON representation.\n *\n * Use {@link jsonToConvex} to recreate the original value.\n *\n * To learn more about Convex values, see [Types](https://docs.convex.dev/using/types).\n *\n * @param value - A Convex value to convert into JSON.\n * @returns The JSON representation of `value`.\n *\n * @public\n */\nexport function convexToJson(value: Value): JSONValue {\n return convexToJsonInternal(value, value, \"\", false);\n}\n\n// Convert a Convex value or `undefined` into its JSON representation.\n// `undefined` is used in filters to represent a missing object field.\nexport function convexOrUndefinedToJson(value: Value | undefined): JSONValue {\n return convexOrUndefinedToJsonInternal(value, value, \"\");\n}\n\n/**\n * Similar to convexToJson but also serializes top level undefined fields\n * using convexOrUndefinedToJson().\n *\n * @param value - A Convex value to convert into JSON.\n * @returns The JSON representation of `value`.\n */\nexport function patchValueToJson(value: Value): JSONValue {\n return convexToJsonInternal(value, value, \"\", true);\n}\n", "import { Value, stringifyValueForError } from \"./value.js\";\n\nconst IDENTIFYING_FIELD = Symbol.for(\"ConvexError\");\n\nexport class ConvexError<TData extends Value> extends Error {\n name = \"ConvexError\";\n data: TData;\n [IDENTIFYING_FIELD] = true;\n\n constructor(data: TData) {\n super(typeof data === \"string\" ? data : stringifyValueForError(data));\n this.data = data;\n }\n}\n", "/* eslint-disable no-console */ // This is the one file where we can `console.log` for the default logger implementation.\nimport { ConvexError, Value } from \"../values/index.js\";\nimport { FunctionFailure } from \"./sync/function_result.js\";\n\n// This is blue #9 from https://www.radix-ui.com/docs/colors/palette-composition/the-scales\n// It must look good in both light and dark mode.\nconst INFO_COLOR = \"color:rgb(0, 145, 255)\";\n\nexport type UdfType = \"query\" | \"mutation\" | \"action\" | \"any\";\n\nfunction prefix_for_source(source: UdfType) {\n switch (source) {\n case \"query\":\n return \"Q\";\n case \"mutation\":\n return \"M\";\n case \"action\":\n return \"A\";\n case \"any\":\n return \"?\";\n }\n}\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/**\n * A logger that can be used to log messages. By default, this is a wrapper\n * around `console`, but can be configured to not log at all or to log somewhere\n * else.\n */\nexport type Logger = {\n logVerbose(...args: any[]): void;\n log(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n};\n\nexport class DefaultLogger implements Logger {\n private _onLogLineFuncs: Record<\n string,\n (level: LogLevel, ...args: any[]) => void\n >;\n private _verbose: boolean;\n\n constructor(options: { verbose: boolean }) {\n this._onLogLineFuncs = {};\n this._verbose = options.verbose;\n }\n\n addLogLineListener(\n func: (level: LogLevel, ...args: any[]) => void,\n ): () => void {\n let id = Math.random().toString(36).substring(2, 15);\n for (let i = 0; i < 10; i++) {\n if (this._onLogLineFuncs[id] === undefined) {\n break;\n }\n id = Math.random().toString(36).substring(2, 15);\n }\n this._onLogLineFuncs[id] = func;\n return () => {\n delete this._onLogLineFuncs[id];\n };\n }\n\n logVerbose(...args: any[]) {\n if (this._verbose) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"debug\", `${new Date().toISOString()}`, ...args);\n }\n }\n }\n\n log(...args: any[]) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"info\", ...args);\n }\n }\n\n warn(...args: any[]) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"warn\", ...args);\n }\n }\n\n error(...args: any[]) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"error\", ...args);\n }\n }\n}\n\nexport function instantiateDefaultLogger(options: {\n verbose: boolean;\n}): Logger {\n const logger = new DefaultLogger(options);\n logger.addLogLineListener((level, ...args) => {\n switch (level) {\n case \"debug\":\n console.debug(...args);\n break;\n case \"info\":\n console.log(...args);\n break;\n case \"warn\":\n console.warn(...args);\n break;\n case \"error\":\n console.error(...args);\n break;\n default: {\n level satisfies never;\n console.log(...args);\n }\n }\n });\n return logger;\n}\n\nexport function instantiateNoopLogger(options: { verbose: boolean }): Logger {\n return new DefaultLogger(options);\n}\n\nexport function logForFunction(\n logger: Logger,\n type: \"info\" | \"error\",\n source: UdfType,\n udfPath: string,\n message: string | { errorData: Value },\n) {\n const prefix = prefix_for_source(source);\n\n if (typeof message === \"object\") {\n message = `ConvexError ${JSON.stringify(message.errorData, null, 2)}`;\n }\n if (type === \"info\") {\n const match = message.match(/^\\[.*?\\] /);\n if (match === null) {\n logger.error(\n `[CONVEX ${prefix}(${udfPath})] Could not parse console.log`,\n );\n return;\n }\n const level = message.slice(1, match[0].length - 2);\n const args = message.slice(match[0].length);\n\n logger.log(`%c[CONVEX ${prefix}(${udfPath})] [${level}]`, INFO_COLOR, args);\n } else {\n logger.error(`[CONVEX ${prefix}(${udfPath})] ${message}`);\n }\n}\n\nexport function logFatalError(logger: Logger, message: string): Error {\n const errorMessage = `[CONVEX FATAL ERROR] ${message}`;\n logger.error(errorMessage);\n return new Error(errorMessage);\n}\n\nexport function createHybridErrorStacktrace(\n source: UdfType,\n udfPath: string,\n result: FunctionFailure,\n): string {\n const prefix = prefix_for_source(source);\n return `[CONVEX ${prefix}(${udfPath})] ${result.errorMessage}\\n Called by client`;\n}\n\nexport function forwardData(\n result: FunctionFailure,\n error: ConvexError<string>,\n) {\n (error as ConvexError<any>).data = result.errorData;\n return error;\n}\n", "import { convexToJson, Value } from \"../../values/index.js\";\n\nexport function canonicalizeUdfPath(udfPath: string): string {\n const pieces = udfPath.split(\":\");\n let moduleName: string;\n let functionName: string;\n if (pieces.length === 1) {\n moduleName = pieces[0];\n functionName = \"default\";\n } else {\n moduleName = pieces.slice(0, pieces.length - 1).join(\":\");\n functionName = pieces[pieces.length - 1];\n }\n if (moduleName.endsWith(\".js\")) {\n moduleName = moduleName.slice(0, -3);\n }\n return `${moduleName}:${functionName}`;\n}\n\n/**\n * The serialization here is not stable, these strings never make it outside the client.\n */\n\n/**\n * A string representing the name and arguments of a query.\n *\n * This is used by the {@link BaseConvexClient}.\n *\n * @public\n */\nexport type QueryToken = string & { __queryToken: true };\n\n/**\n * A string representing the name and arguments of a paginated query.\n *\n * This is a specialized form of QueryToken used for paginated queries.\n */\nexport type PaginatedQueryToken = QueryToken & { __paginatedQueryToken: true };\n\nexport function serializePathAndArgs(\n udfPath: string,\n args: Record<string, Value>,\n): QueryToken {\n return JSON.stringify({\n udfPath: canonicalizeUdfPath(udfPath),\n args: convexToJson(args),\n }) as QueryToken;\n}\n\nexport function serializePaginatedPathAndArgs(\n udfPath: string,\n args: Record<string, Value>, // args WITHOUT paginationOpts\n options: { initialNumItems: number; id: number },\n): PaginatedQueryToken {\n const { initialNumItems, id } = options;\n const result = JSON.stringify({\n type: \"paginated\",\n udfPath: canonicalizeUdfPath(udfPath),\n args: convexToJson(args),\n options: convexToJson({ initialNumItems, id }),\n }) as PaginatedQueryToken;\n return result;\n}\n\nexport function serializedQueryTokenIsPaginated(\n token: QueryToken | PaginatedQueryToken,\n): token is PaginatedQueryToken {\n return JSON.parse(token).type === \"paginated\";\n}\n", "/**\n * The local state of the client:\n * - which queries are subscribed to\n * - the \"Query Set Version,\" used to produce QuerySetModification messages\n * - the current auth token and \"Identity Version\"\n *\n * Local state does not include:\n * - query results (see RemoteQuerySet)\n * - locally made \"optimistic update\" modifications to query results (see OptimisticQueryResults)\n * - any query results at all\n **/\n\nimport { convexToJson, Value } from \"../../values/index.js\";\nimport {\n AddQuery,\n RemoveQuery,\n QueryId,\n QuerySetModification,\n QuerySetVersion,\n IdentityVersion,\n Authenticate,\n QueryJournal,\n Transition,\n AdminAuthentication,\n UserIdentityAttributes,\n} from \"./protocol.js\";\nimport {\n canonicalizeUdfPath,\n QueryToken,\n serializePathAndArgs,\n} from \"./udf_path_utils.js\";\n\ntype LocalQuery = {\n id: QueryId;\n canonicalizedUdfPath: string;\n args: Record<string, Value>;\n numSubscribers: number;\n journal?: QueryJournal | undefined;\n componentPath?: string | undefined;\n};\n\nexport type AuthState =\n | {\n tokenType: \"User\";\n value: string;\n }\n | {\n tokenType: \"Admin\";\n value: string;\n impersonating?: UserIdentityAttributes | undefined;\n };\n\nexport class LocalSyncState {\n private nextQueryId: QueryId;\n private querySetVersion: QuerySetVersion;\n private readonly querySet: Map<QueryToken, LocalQuery>;\n private readonly queryIdToToken: Map<QueryId, QueryToken>;\n private identityVersion: IdentityVersion;\n private auth: AuthState | undefined;\n private readonly outstandingQueriesOlderThanRestart: Set<QueryId>;\n private outstandingAuthOlderThanRestart: boolean;\n private paused: boolean;\n private pendingQuerySetModifications: Map<QueryId, AddQuery | RemoveQuery>;\n\n constructor() {\n this.nextQueryId = 0;\n this.querySetVersion = 0;\n this.identityVersion = 0;\n this.querySet = new Map();\n this.queryIdToToken = new Map();\n this.outstandingQueriesOlderThanRestart = new Set();\n this.outstandingAuthOlderThanRestart = false;\n this.paused = false;\n this.pendingQuerySetModifications = new Map();\n }\n\n hasSyncedPastLastReconnect(): boolean {\n return (\n this.outstandingQueriesOlderThanRestart.size === 0 &&\n !this.outstandingAuthOlderThanRestart\n );\n }\n\n markAuthCompletion() {\n this.outstandingAuthOlderThanRestart = false;\n }\n\n subscribe(\n udfPath: string,\n args: Record<string, Value>,\n journal?: QueryJournal | undefined,\n componentPath?: string | undefined,\n ): {\n queryToken: QueryToken;\n modification: QuerySetModification | null;\n unsubscribe: () => QuerySetModification | null;\n } {\n const canonicalizedUdfPath = canonicalizeUdfPath(udfPath);\n const queryToken = serializePathAndArgs(canonicalizedUdfPath, args);\n\n const existingEntry = this.querySet.get(queryToken);\n\n if (existingEntry !== undefined) {\n existingEntry.numSubscribers += 1;\n return {\n queryToken,\n modification: null,\n unsubscribe: () => this.removeSubscriber(queryToken),\n };\n } else {\n const queryId = this.nextQueryId++;\n const query: LocalQuery = {\n id: queryId,\n canonicalizedUdfPath,\n args,\n numSubscribers: 1,\n journal,\n componentPath,\n };\n this.querySet.set(queryToken, query);\n this.queryIdToToken.set(queryId, queryToken);\n\n const baseVersion = this.querySetVersion;\n const newVersion = this.querySetVersion + 1;\n\n const add: AddQuery = {\n type: \"Add\",\n queryId,\n udfPath: canonicalizedUdfPath,\n args: [convexToJson(args)],\n journal,\n componentPath,\n };\n\n if (this.paused) {\n this.pendingQuerySetModifications.set(queryId, add);\n } else {\n this.querySetVersion = newVersion;\n }\n\n const modification: QuerySetModification = {\n type: \"ModifyQuerySet\",\n baseVersion,\n newVersion,\n modifications: [add],\n };\n return {\n queryToken,\n modification,\n unsubscribe: () => this.removeSubscriber(queryToken),\n };\n }\n }\n\n transition(transition: Transition) {\n for (const modification of transition.modifications) {\n switch (modification.type) {\n case \"QueryUpdated\":\n case \"QueryFailed\": {\n this.outstandingQueriesOlderThanRestart.delete(modification.queryId);\n const journal = modification.journal;\n if (journal !== undefined) {\n const queryToken = this.queryIdToToken.get(modification.queryId);\n // We may have already unsubscribed to this query by the time the server\n // sends us the journal. If so, just ignore it.\n if (queryToken !== undefined) {\n this.querySet.get(queryToken)!.journal = journal;\n }\n }\n\n break;\n }\n case \"QueryRemoved\": {\n this.outstandingQueriesOlderThanRestart.delete(modification.queryId);\n break;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n modification satisfies never;\n throw new Error(`Invalid modification ${(modification as any).type}`);\n }\n }\n }\n }\n\n queryId(udfPath: string, args: Record<string, Value>): QueryId | null {\n const canonicalizedUdfPath = canonicalizeUdfPath(udfPath);\n const queryToken = serializePathAndArgs(canonicalizedUdfPath, args);\n const existingEntry = this.querySet.get(queryToken);\n if (existingEntry !== undefined) {\n return existingEntry.id;\n }\n return null;\n }\n\n isCurrentOrNewerAuthVersion(version: IdentityVersion): boolean {\n return version >= this.identityVersion;\n }\n\n getAuth(): AuthState | undefined {\n return this.auth;\n }\n\n setAuth(value: string): Authenticate {\n this.auth = {\n tokenType: \"User\" as const,\n value: value,\n };\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n baseVersion: baseVersion,\n ...this.auth,\n };\n }\n\n setAdminAuth(\n value: string,\n actingAs?: UserIdentityAttributes,\n ): AdminAuthentication {\n const auth: typeof this.auth & {\n tokenType: \"Admin\";\n } = {\n tokenType: \"Admin\",\n value,\n impersonating: actingAs,\n };\n this.auth = auth;\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n baseVersion: baseVersion,\n ...auth,\n };\n }\n\n clearAuth(): Authenticate {\n this.auth = undefined;\n this.markAuthCompletion();\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n tokenType: \"None\",\n baseVersion: baseVersion,\n };\n }\n\n hasAuth(): boolean {\n return !!this.auth;\n }\n\n isNewAuth(value: string): boolean {\n return this.auth?.value !== value;\n }\n\n queryPath(queryId: QueryId): string | null {\n const pathAndArgs = this.queryIdToToken.get(queryId);\n if (pathAndArgs) {\n return this.querySet.get(pathAndArgs)!.canonicalizedUdfPath;\n }\n return null;\n }\n\n queryArgs(queryId: QueryId): Record<string, Value> | null {\n const pathAndArgs = this.queryIdToToken.get(queryId);\n if (pathAndArgs) {\n return this.querySet.get(pathAndArgs)!.args;\n }\n return null;\n }\n\n queryToken(queryId: QueryId): QueryToken | null {\n return this.queryIdToToken.get(queryId) ?? null;\n }\n\n queryJournal(queryToken: QueryToken): QueryJournal | undefined {\n return this.querySet.get(queryToken)?.journal;\n }\n\n restart(): [QuerySetModification, (Authenticate | undefined)?] {\n // Restart works whether we are paused or unpaused.\n // The `this.pendingQuerySetModifications` is not used\n // when restarting as the AddQuery and RemoveQuery are computed\n // from scratch, based on the old remote query results, here.\n this.unpause();\n\n this.outstandingQueriesOlderThanRestart.clear();\n const modifications = [];\n for (const localQuery of this.querySet.values()) {\n const add: AddQuery = {\n type: \"Add\",\n queryId: localQuery.id,\n udfPath: localQuery.canonicalizedUdfPath,\n args: [convexToJson(localQuery.args)],\n journal: localQuery.journal,\n componentPath: localQuery.componentPath,\n };\n modifications.push(add);\n\n // Track all re-sent queries as outstanding so the backoff retry\n // counter doesn't reset until the server has re-confirmed results\n // for every active query.\n this.outstandingQueriesOlderThanRestart.add(localQuery.id);\n }\n this.querySetVersion = 1;\n const querySet: QuerySetModification = {\n type: \"ModifyQuerySet\",\n baseVersion: 0,\n newVersion: 1,\n modifications,\n };\n // If there's no auth, no need to send an update as the server will also start with an unknown identity.\n if (!this.auth) {\n this.identityVersion = 0;\n return [querySet, undefined];\n }\n this.outstandingAuthOlderThanRestart = true;\n const authenticate: Authenticate = {\n type: \"Authenticate\",\n baseVersion: 0,\n ...this.auth,\n };\n this.identityVersion = 1;\n return [querySet, authenticate];\n }\n\n pause() {\n this.paused = true;\n }\n\n resume(): [QuerySetModification | undefined, Authenticate | undefined] {\n const querySet: QuerySetModification | undefined =\n this.pendingQuerySetModifications.size > 0\n ? {\n type: \"ModifyQuerySet\",\n baseVersion: this.querySetVersion,\n newVersion: ++this.querySetVersion,\n modifications: Array.from(\n this.pendingQuerySetModifications.values(),\n ),\n }\n : undefined;\n const authenticate: Authenticate | undefined =\n this.auth !== undefined\n ? {\n type: \"Authenticate\",\n baseVersion: this.identityVersion++,\n ...this.auth,\n }\n : undefined;\n\n this.unpause();\n\n return [querySet, authenticate];\n }\n\n private unpause() {\n this.paused = false;\n this.pendingQuerySetModifications.clear();\n }\n\n private removeSubscriber(\n queryToken: QueryToken,\n ): QuerySetModification | null {\n const localQuery = this.querySet.get(queryToken)!;\n\n if (localQuery.numSubscribers > 1) {\n localQuery.numSubscribers -= 1;\n return null;\n } else {\n this.querySet.delete(queryToken);\n this.queryIdToToken.delete(localQuery.id);\n this.outstandingQueriesOlderThanRestart.delete(localQuery.id);\n const baseVersion = this.querySetVersion;\n const newVersion = this.querySetVersion + 1;\n const remove: RemoveQuery = {\n type: \"Remove\",\n queryId: localQuery.id,\n };\n if (this.paused) {\n if (this.pendingQuerySetModifications.has(localQuery.id)) {\n this.pendingQuerySetModifications.delete(localQuery.id);\n } else {\n this.pendingQuerySetModifications.set(localQuery.id, remove);\n }\n } else {\n this.querySetVersion = newVersion;\n }\n return {\n type: \"ModifyQuerySet\",\n baseVersion,\n newVersion,\n modifications: [remove],\n };\n }\n }\n}\n", "import { jsonToConvex } from \"../../values/index.js\";\nimport { logForFunction, Logger } from \"../logging.js\";\nimport { Long } from \"../../vendor/long.js\";\nimport { FunctionResult } from \"./function_result.js\";\nimport {\n ActionRequest,\n ActionResponse,\n ClientMessage,\n MutationRequest,\n MutationResponse,\n RequestId,\n} from \"./protocol.js\";\n\ntype RequestStatus =\n | {\n status: \"Requested\" | \"NotSent\";\n onResult: (result: FunctionResult) => void;\n requestedAt: Date;\n }\n | {\n status: \"Completed\";\n result: FunctionResult;\n onResolve: () => void;\n ts: Long;\n };\n\nexport class RequestManager {\n private inflightRequests: Map<\n RequestId,\n {\n message: MutationRequest | ActionRequest;\n status: RequestStatus;\n }\n >;\n private requestsOlderThanRestart: Set<RequestId>;\n private inflightMutationsCount: number = 0;\n private inflightActionsCount: number = 0;\n constructor(\n private readonly logger: Logger,\n private readonly markConnectionStateDirty: () => void,\n ) {\n this.inflightRequests = new Map();\n this.requestsOlderThanRestart = new Set();\n }\n\n request(\n message: MutationRequest | ActionRequest,\n sent: boolean,\n ): Promise<FunctionResult> {\n const result = new Promise<FunctionResult>((resolve) => {\n const status = sent ? \"Requested\" : \"NotSent\";\n this.inflightRequests.set(message.requestId, {\n message,\n status: { status, requestedAt: new Date(), onResult: resolve },\n });\n\n if (message.type === \"Mutation\") {\n this.inflightMutationsCount++;\n } else if (message.type === \"Action\") {\n this.inflightActionsCount++;\n }\n });\n\n this.markConnectionStateDirty();\n return result;\n }\n\n /**\n * Update the state after receiving a response.\n *\n * @returns A RequestId if the request is complete and its optimistic update\n * can be dropped, null otherwise.\n */\n onResponse(\n response: MutationResponse | ActionResponse,\n ): { requestId: RequestId; result: FunctionResult } | null {\n const requestInfo = this.inflightRequests.get(response.requestId);\n if (requestInfo === undefined) {\n // Annoyingly we can occasionally get responses to mutations that we're no\n // longer tracking. One flow where this happens is:\n // 1. Client sends mutation 1\n // 2. Client gets response for mutation 1. The sever says that it was committed at ts=10.\n // 3. Client is disconnected\n // 4. Client reconnects and re-issues queries and this mutation.\n // 5. Server sends transition message to ts=20\n // 6. Client drops mutation because it's already been observed.\n // 7. Client receives a second response for mutation 1 but doesn't know about it anymore.\n\n // The right fix for this is probably to add a reconciliation phase on\n // reconnection where we receive responses to all the mutations before\n // the transition message so this flow could never happen (CX-1513).\n\n // For now though, we can just ignore this message.\n return null;\n }\n\n // Because `.restart()` re-requests completed requests, we may get some\n // responses for requests that are already in the \"Completed\" state.\n // We can safely ignore those because we've already notified the UI about\n // their results.\n if (requestInfo.status.status === \"Completed\") {\n return null;\n }\n\n const udfType =\n requestInfo.message.type === \"Mutation\" ? \"mutation\" : \"action\";\n const udfPath = requestInfo.message.udfPath;\n\n for (const line of response.logLines) {\n logForFunction(this.logger, \"info\", udfType, udfPath, line);\n }\n\n const status = requestInfo.status;\n let result: FunctionResult;\n let onResolve;\n if (response.success) {\n result = {\n success: true,\n logLines: response.logLines,\n value: jsonToConvex(response.result),\n };\n onResolve = () => status.onResult(result);\n } else {\n const errorMessage = response.result as string;\n const { errorData } = response;\n logForFunction(this.logger, \"error\", udfType, udfPath, errorMessage);\n result = {\n success: false,\n errorMessage,\n errorData:\n errorData !== undefined ? jsonToConvex(errorData) : undefined,\n logLines: response.logLines,\n };\n onResolve = () => status.onResult(result);\n }\n\n // We can resolve Mutation failures immediately since they don't have any\n // side effects. Actions are intentionally decoupled from\n // queries/mutations here on the sync protocol since they have different\n // guarantees.\n if (response.type === \"ActionResponse\" || !response.success) {\n onResolve();\n this.inflightRequests.delete(response.requestId);\n this.requestsOlderThanRestart.delete(response.requestId);\n\n if (requestInfo.message.type === \"Action\") {\n this.inflightActionsCount--;\n } else if (requestInfo.message.type === \"Mutation\") {\n this.inflightMutationsCount--;\n }\n\n this.markConnectionStateDirty();\n return { requestId: response.requestId, result };\n }\n\n // We have to wait to resolve the request promise until after we transition\n // past this timestamp so clients can read their own writes.\n requestInfo.status = {\n status: \"Completed\",\n result,\n ts: response.ts,\n onResolve,\n };\n\n return null;\n }\n\n // Remove and returns completed requests.\n removeCompleted(ts: Long): Map<RequestId, FunctionResult> {\n const completeRequests: Map<RequestId, FunctionResult> = new Map();\n for (const [requestId, requestInfo] of this.inflightRequests.entries()) {\n const status = requestInfo.status;\n if (status.status === \"Completed\" && status.ts.lessThanOrEqual(ts)) {\n status.onResolve();\n completeRequests.set(requestId, status.result);\n\n if (requestInfo.message.type === \"Mutation\") {\n this.inflightMutationsCount--;\n } else if (requestInfo.message.type === \"Action\") {\n this.inflightActionsCount--;\n }\n\n this.inflightRequests.delete(requestId);\n this.requestsOlderThanRestart.delete(requestId);\n }\n }\n if (completeRequests.size > 0) {\n this.markConnectionStateDirty();\n }\n return completeRequests;\n }\n\n restart(): ClientMessage[] {\n // When we reconnect to the backend, re-request all requests that are safe\n // to be resend.\n\n this.requestsOlderThanRestart = new Set(this.inflightRequests.keys());\n const allMessages = [];\n for (const [requestId, value] of this.inflightRequests) {\n if (value.status.status === \"NotSent\") {\n value.status.status = \"Requested\";\n allMessages.push(value.message);\n continue;\n }\n\n if (value.message.type === \"Mutation\") {\n // This includes ones that have already been completed because we still\n // want to tell the backend to transition the client past the completed\n // timestamp. This is safe since mutations are idempotent.\n allMessages.push(value.message);\n } else if (value.message.type === \"Action\") {\n // Unlike mutations, actions are not idempotent. When we reconnect to the\n // backend, we don't know if it is safe to resend in-flight actions, so we\n // cancel them and consider them failed.\n this.inflightRequests.delete(requestId);\n this.requestsOlderThanRestart.delete(requestId);\n this.inflightActionsCount--;\n if (value.status.status === \"Completed\") {\n throw new Error(\"Action should never be in 'Completed' state\");\n }\n value.status.onResult({\n success: false,\n errorMessage: \"Connection lost while action was in flight\",\n logLines: [],\n });\n }\n }\n this.markConnectionStateDirty();\n return allMessages;\n }\n\n resume(): ClientMessage[] {\n const allMessages = [];\n for (const [, value] of this.inflightRequests) {\n if (value.status.status === \"NotSent\") {\n value.status.status = \"Requested\";\n allMessages.push(value.message);\n continue;\n }\n }\n return allMessages;\n }\n\n /**\n * @returns true if there are any requests that have been requested but have\n * not be completed yet.\n */\n hasIncompleteRequests(): boolean {\n for (const requestInfo of this.inflightRequests.values()) {\n if (requestInfo.status.status === \"Requested\") {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @returns true if there are any inflight requests, including ones that have\n * completed on the server, but have not been applied.\n */\n hasInflightRequests(): boolean {\n return this.inflightRequests.size > 0;\n }\n\n /**\n * @returns true if there are any inflight requests, that have been hanging around\n * since prior to the most recent restart.\n */\n hasSyncedPastLastReconnect(): boolean {\n return this.requestsOlderThanRestart.size === 0;\n }\n\n timeOfOldestInflightRequest(): Date | null {\n if (this.inflightRequests.size === 0) {\n return null;\n }\n let oldestInflightRequest = Date.now();\n for (const request of this.inflightRequests.values()) {\n if (request.status.status !== \"Completed\") {\n if (request.status.requestedAt.getTime() < oldestInflightRequest) {\n oldestInflightRequest = request.status.requestedAt.getTime();\n }\n }\n }\n return new Date(oldestInflightRequest);\n }\n\n /**\n * @returns The number of mutations currently in flight.\n */\n inflightMutations(): number {\n return this.inflightMutationsCount;\n }\n\n /**\n * @returns The number of actions currently in flight.\n */\n inflightActions(): number {\n return this.inflightActionsCount;\n }\n}\n", "/**\n * A symbol for accessing the name of a {@link FunctionReference} at runtime.\n */\nexport const functionName = Symbol.for(\"functionName\");\n", "import { functionName } from \"../functionName.js\";\n\nexport const toReferencePath = Symbol.for(\"toReferencePath\");\n\n// Multiple instances of the same Symbol.for() are equal at runtime but not\n// at type-time, so `[toReferencePath]` properties aren't used in types.\n// Use this function to set the property invisibly.\nexport function setReferencePath<T>(obj: T, value: string) {\n (obj as any)[toReferencePath] = value;\n}\n\nexport function extractReferencePath(reference: any): string | null {\n return reference[toReferencePath] ?? null;\n}\n\nexport function isFunctionHandle(s: string): boolean {\n return s.startsWith(\"function://\");\n}\n\nexport function getFunctionAddress(functionReference: any) {\n // The `run*` syscalls expect either a UDF path at \"name\" or a serialized\n // reference at \"reference\". Dispatch on `functionReference` to coerce\n // it to one or the other.\n let functionAddress;\n\n // Legacy path for passing in UDF paths directly as function references.\n if (typeof functionReference === \"string\") {\n if (isFunctionHandle(functionReference)) {\n functionAddress = { functionHandle: functionReference };\n } else {\n functionAddress = { name: functionReference };\n }\n }\n // Path for passing in a `FunctionReference`, either from `api` or directly\n // created from a UDF path with `makeFunctionReference`.\n else if (functionReference[functionName]) {\n functionAddress = { name: functionReference[functionName] };\n }\n // Reference to a component's function derived from `app` or `component`.\n else {\n const referencePath = extractReferencePath(functionReference);\n if (!referencePath) {\n throw new Error(`${functionReference} is not a functionReference`);\n }\n functionAddress = { reference: referencePath };\n }\n return functionAddress;\n}\n", "import {\n EmptyObject,\n DefaultFunctionArgs,\n FunctionVisibility,\n RegisteredAction,\n RegisteredMutation,\n RegisteredQuery,\n} from \"./registration.js\";\nimport { Expand, UnionToIntersection } from \"../type_utils.js\";\nimport { PaginationOptions, PaginationResult } from \"./pagination.js\";\nimport { functionName } from \"./functionName.js\";\nimport { getFunctionAddress } from \"./components/paths.js\";\n\n/**\n * The type of a Convex function.\n *\n * @public\n */\nexport type FunctionType = \"query\" | \"mutation\" | \"action\";\n\n/**\n * A reference to a registered Convex function.\n *\n * You can create a {@link FunctionReference} using the generated `api` utility:\n * ```js\n * import { api } from \"../convex/_generated/api\";\n *\n * const reference = api.myModule.myFunction;\n * ```\n *\n * If you aren't using code generation, you can create references using\n * {@link anyApi}:\n * ```js\n * import { anyApi } from \"convex/server\";\n *\n * const reference = anyApi.myModule.myFunction;\n * ```\n *\n * Function references can be used to invoke functions from the client. For\n * example, in React you can pass references to the {@link react.useQuery} hook:\n * ```js\n * const result = useQuery(api.myModule.myFunction);\n * ```\n *\n * @typeParam Type - The type of the function (\"query\", \"mutation\", or \"action\").\n * @typeParam Visibility - The visibility of the function (\"public\" or \"internal\").\n * @typeParam Args - The arguments to this function. This is an object mapping\n * argument names to their types.\n * @typeParam ReturnType - The return type of this function.\n * @public\n */\nexport type FunctionReference<\n Type extends FunctionType,\n Visibility extends FunctionVisibility = \"public\",\n Args extends DefaultFunctionArgs = any,\n ReturnType = any,\n ComponentPath = string | undefined,\n> = {\n _type: Type;\n _visibility: Visibility;\n _args: Args;\n _returnType: ReturnType;\n _componentPath: ComponentPath;\n};\n\n/**\n * Get the name of a function from a {@link FunctionReference}.\n *\n * The name is a string like \"myDir/myModule:myFunction\". If the exported name\n * of the function is `\"default\"`, the function name is omitted\n * (e.g. \"myDir/myModule\").\n *\n * @param functionReference - A {@link FunctionReference} to get the name of.\n * @returns A string of the function's name.\n *\n * @public\n */\nexport function getFunctionName(\n functionReference: AnyFunctionReference,\n): string {\n const address = getFunctionAddress(functionReference);\n\n if (address.name === undefined) {\n if (address.functionHandle !== undefined) {\n throw new Error(\n `Expected function reference like \"api.file.func\" or \"internal.file.func\", but received function handle ${address.functionHandle}`,\n );\n } else if (address.reference !== undefined) {\n throw new Error(\n `Expected function reference in the current component like \"api.file.func\" or \"internal.file.func\", but received reference ${address.reference}`,\n );\n }\n throw new Error(\n `Expected function reference like \"api.file.func\" or \"internal.file.func\", but received ${JSON.stringify(address)}`,\n );\n }\n // Both a legacy thing and also a convenience for interactive use:\n // the types won't check but a string is always allowed at runtime.\n if (typeof functionReference === \"string\") return functionReference;\n\n // Two different runtime values for FunctionReference implement this\n // interface: api objects returned from `createApi()` and standalone\n // function reference objects returned from makeFunctionReference.\n const name = (functionReference as any)[functionName];\n if (!name) {\n throw new Error(`${functionReference as any} is not a functionReference`);\n }\n return name;\n}\n\n/**\n * FunctionReferences generally come from generated code, but in custom clients\n * it may be useful to be able to build one manually.\n *\n * Real function references are empty objects at runtime, but the same interface\n * can be implemented with an object for tests and clients which don't use\n * code generation.\n *\n * @param name - The identifier of the function. E.g. `path/to/file:functionName`\n * @public\n */\nexport function makeFunctionReference<\n type extends FunctionType,\n args extends DefaultFunctionArgs = any,\n ret = any,\n>(name: string): FunctionReference<type, \"public\", args, ret> {\n return { [functionName]: name } as unknown as FunctionReference<\n type,\n \"public\",\n args,\n ret\n >;\n}\n\n/**\n * Create a runtime API object that implements {@link AnyApi}.\n *\n * This allows accessing any path regardless of what directories, modules,\n * or functions are defined.\n *\n * @param pathParts - The path to the current node in the API.\n * @returns An {@link AnyApi}\n * @public\n */\nfunction createApi(pathParts: string[] = []): AnyApi {\n const handler: ProxyHandler<object> = {\n get(_, prop: string | symbol) {\n if (typeof prop === \"string\") {\n const newParts = [...pathParts, prop];\n return createApi(newParts);\n } else if (prop === functionName) {\n if (pathParts.length < 2) {\n const found = [\"api\", ...pathParts].join(\".\");\n throw new Error(\n `API path is expected to be of the form \\`api.moduleName.functionName\\`. Found: \\`${found}\\``,\n );\n }\n const path = pathParts.slice(0, -1).join(\"/\");\n const exportName = pathParts[pathParts.length - 1];\n if (exportName === \"default\") {\n return path;\n } else {\n return path + \":\" + exportName;\n }\n } else if (prop === Symbol.toStringTag) {\n return \"FunctionReference\";\n } else {\n return undefined;\n }\n },\n };\n\n return new Proxy({}, handler);\n}\n\n/**\n * Given an export from a module, convert it to a {@link FunctionReference}\n * if it is a Convex function.\n */\nexport type FunctionReferenceFromExport<Export> =\n Export extends RegisteredQuery<\n infer Visibility,\n infer Args,\n infer ReturnValue\n >\n ? FunctionReference<\n \"query\",\n Visibility,\n Args,\n ConvertReturnType<ReturnValue>\n >\n : Export extends RegisteredMutation<\n infer Visibility,\n infer Args,\n infer ReturnValue\n >\n ? FunctionReference<\n \"mutation\",\n Visibility,\n Args,\n ConvertReturnType<ReturnValue>\n >\n : Export extends RegisteredAction<\n infer Visibility,\n infer Args,\n infer ReturnValue\n >\n ? FunctionReference<\n \"action\",\n Visibility,\n Args,\n ConvertReturnType<ReturnValue>\n >\n : never;\n\n/**\n * Given a module, convert all the Convex functions into\n * {@link FunctionReference}s and remove the other exports.\n *\n * BE CAREFUL WHEN EDITING THIS!\n *\n * This is written carefully to preserve jumping to function definitions using\n * cmd+click. If you edit it, please test that cmd+click still works.\n */\ntype FunctionReferencesInModule<Module extends Record<string, any>> = {\n -readonly [ExportName in keyof Module as Module[ExportName][\"isConvexFunction\"] extends true\n ? ExportName\n : never]: FunctionReferenceFromExport<Module[ExportName]>;\n};\n\n/**\n * Given a path to a module and it's type, generate an API type for this module.\n *\n * This is a nested object according to the module's path.\n */\ntype ApiForModule<\n ModulePath extends string,\n Module extends object,\n> = ModulePath extends `${infer First}/${infer Second}`\n ? {\n [_ in First]: ApiForModule<Second, Module>;\n }\n : { [_ in ModulePath]: FunctionReferencesInModule<Module> };\n\n/**\n * Given the types of all modules in the `convex/` directory, construct the type\n * of `api`.\n *\n * `api` is a utility for constructing {@link FunctionReference}s.\n *\n * @typeParam AllModules - A type mapping module paths (like `\"dir/myModule\"`) to\n * the types of the modules.\n * @public\n */\nexport type ApiFromModules<AllModules extends Record<string, object>> =\n FilterApi<\n ApiFromModulesAllowEmptyNodes<AllModules>,\n FunctionReference<any, any, any, any>\n >;\n\ntype ApiFromModulesAllowEmptyNodes<AllModules extends Record<string, object>> =\n ExpandModulesAndDirs<\n UnionToIntersection<\n {\n [ModulePath in keyof AllModules]: ApiForModule<\n ModulePath & string,\n AllModules[ModulePath]\n >;\n }[keyof AllModules]\n >\n >;\n\ntype FilterKeysInApi<key, API, Predicate> = API extends Predicate\n ? key\n : API extends FunctionReference<any, any, any, any>\n ? never\n : FilterApi<API, Predicate> extends Record<string, never>\n ? never\n : key;\n\n/**\n * @public\n *\n * Filter a Convex deployment api object for functions which meet criteria,\n * for example all public queries.\n */\nexport type FilterApi<API, Predicate> = Expand<{\n [mod in keyof API as FilterKeysInApi<\n mod,\n API[mod],\n Predicate\n >]: API[mod] extends Predicate ? API[mod] : FilterApi<API[mod], Predicate>;\n}>;\n\n/**\n * Given an api of type API and a FunctionReference subtype, return an api object\n * containing only the function references that match.\n *\n * ```ts\n * const q = filterApi<typeof api, FunctionReference<\"query\">>(api)\n * ```\n *\n * @public\n */\nexport function filterApi<API, Predicate>(api: API): FilterApi<API, Predicate> {\n return api as any;\n}\n\n// These just* API filter helpers require no type parameters so are useable from JavaScript.\n/** @public */\nexport function justInternal<API>(\n api: API,\n): FilterApi<API, FunctionReference<any, \"internal\", any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justPublic<API>(\n api: API,\n): FilterApi<API, FunctionReference<any, \"public\", any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justQueries<API>(\n api: API,\n): FilterApi<API, FunctionReference<\"query\", any, any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justMutations<API>(\n api: API,\n): FilterApi<API, FunctionReference<\"mutation\", any, any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justActions<API>(\n api: API,\n): FilterApi<API, FunctionReference<\"action\", any, any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justPaginatedQueries<API>(\n api: API,\n): FilterApi<\n API,\n FunctionReference<\n \"query\",\n any,\n { paginationOpts: PaginationOptions },\n PaginationResult<any>\n >\n> {\n return api as any;\n}\n\n/** @public */\nexport function justSchedulable<API>(\n api: API,\n): FilterApi<API, FunctionReference<\"mutation\" | \"action\", any, any, any>> {\n return api as any;\n}\n\n/**\n * Like {@link Expand}, this simplifies how TypeScript displays object types.\n * The differences are:\n * 1. This version is recursive.\n * 2. This stops recursing when it hits a {@link FunctionReference}.\n */\ntype ExpandModulesAndDirs<ObjectType> = ObjectType extends AnyFunctionReference\n ? ObjectType\n : {\n [Key in keyof ObjectType]: ExpandModulesAndDirs<ObjectType[Key]>;\n };\n\n/**\n * A {@link FunctionReference} of any type and any visibility with any\n * arguments and any return type.\n *\n * @public\n */\nexport type AnyFunctionReference = FunctionReference<any, any>;\n\ntype AnyModuleDirOrFunc = {\n [key: string]: AnyModuleDirOrFunc;\n} & AnyFunctionReference;\n\n/**\n * The type that Convex api objects extend. If you were writing an api from\n * scratch it should extend this type.\n *\n * @public\n */\nexport type AnyApi = Record<string, Record<string, AnyModuleDirOrFunc>>;\n\n/**\n * Recursive partial API, useful for defining a subset of an API when mocking\n * or building custom api objects.\n *\n * @public\n */\nexport type PartialApi<API> = {\n [mod in keyof API]?: API[mod] extends FunctionReference<any, any, any, any>\n ? API[mod]\n : PartialApi<API[mod]>;\n};\n\n/**\n * A utility for constructing {@link FunctionReference}s in projects that\n * are not using code generation.\n *\n * You can create a reference to a function like:\n * ```js\n * const reference = anyApi.myModule.myFunction;\n * ```\n *\n * This supports accessing any path regardless of what directories and modules\n * are in your project. All function references are typed as\n * {@link AnyFunctionReference}.\n *\n *\n * If you're using code generation, use `api` from `convex/_generated/api`\n * instead. It will be more type-safe and produce better auto-complete\n * in your editor.\n *\n * @public\n */\nexport const anyApi: AnyApi = createApi() as any;\n\n/**\n * Given a {@link FunctionReference}, get the return type of the function.\n *\n * This is represented as an object mapping argument names to values.\n * @public\n */\nexport type FunctionArgs<FuncRef extends AnyFunctionReference> =\n FuncRef[\"_args\"];\n\n/**\n * A tuple type of the (maybe optional) arguments to `FuncRef`.\n *\n * This type is used to make methods involving arguments type safe while allowing\n * skipping the arguments for functions that don't require arguments.\n *\n * @public\n */\nexport type OptionalRestArgs<FuncRef extends AnyFunctionReference> =\n FuncRef[\"_args\"] extends EmptyObject\n ? [args?: EmptyObject]\n : [args: FuncRef[\"_args\"]];\n\n/**\n * A tuple type of the (maybe optional) arguments to `FuncRef`, followed by an options\n * object of type `Options`.\n *\n * This type is used to make methods like `useQuery` type-safe while allowing\n * 1. Skipping arguments for functions that don't require arguments.\n * 2. Skipping the options object.\n * @public\n */\nexport type ArgsAndOptions<\n FuncRef extends AnyFunctionReference,\n Options,\n> = FuncRef[\"_args\"] extends EmptyObject\n ? [args?: EmptyObject, options?: Options]\n : [args: FuncRef[\"_args\"], options?: Options];\n\n/**\n * Given a {@link FunctionReference}, get the return type of the function.\n *\n * @public\n */\nexport type FunctionReturnType<FuncRef extends AnyFunctionReference> =\n FuncRef[\"_returnType\"];\n\ntype UndefinedToNull<T> = T extends void ? null : T;\n\ntype NullToUndefinedOrNull<T> = T extends null ? T | undefined | void : T;\n\n/**\n * Convert the return type of a function to it's client-facing format.\n *\n * This means:\n * - Converting `undefined` and `void` to `null`\n * - Removing all `Promise` wrappers\n */\nexport type ConvertReturnType<T> = UndefinedToNull<Awaited<T>>;\n\nexport type ValidatorTypeToReturnType<T> =\n | Promise<NullToUndefinedOrNull<T>>\n | NullToUndefinedOrNull<T>;\n", "import {\n FunctionArgs,\n FunctionReference,\n FunctionReturnType,\n OptionalRestArgs,\n getFunctionName,\n} from \"../../server/api.js\";\nimport { parseArgs } from \"../../common/index.js\";\nimport { Value } from \"../../values/index.js\";\nimport { createHybridErrorStacktrace, forwardData } from \"../logging.js\";\nimport { FunctionResult } from \"./function_result.js\";\nimport { OptimisticLocalStore } from \"./optimistic_updates.js\";\nimport { RequestId } from \"./protocol.js\";\nimport {\n canonicalizeUdfPath,\n QueryToken,\n serializePathAndArgs,\n} from \"./udf_path_utils.js\";\nimport { ConvexError } from \"../../values/errors.js\";\n\n/**\n * An optimistic update function that has been curried over its arguments.\n */\ntype WrappedOptimisticUpdate = (locaQueryStore: OptimisticLocalStore) => void;\n\n/**\n * The implementation of `OptimisticLocalStore`.\n *\n * This class provides the interface for optimistic updates to modify query results.\n */\nclass OptimisticLocalStoreImpl implements OptimisticLocalStore {\n // A references of the query results in OptimisticQueryResults\n private readonly queryResults: QueryResultsMap;\n\n // All of the queries modified by this class\n readonly modifiedQueries: QueryToken[];\n\n constructor(queryResults: QueryResultsMap) {\n this.queryResults = queryResults;\n this.modifiedQueries = [];\n }\n\n getQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgs<Query>\n ): undefined | FunctionReturnType<Query> {\n const queryArgs = parseArgs(args[0]);\n const name = getFunctionName(query);\n const queryResult = this.queryResults.get(\n serializePathAndArgs(name, queryArgs),\n );\n if (queryResult === undefined) {\n return undefined;\n }\n return OptimisticLocalStoreImpl.queryValue(queryResult.result);\n }\n\n getAllQueries<Query extends FunctionReference<\"query\">>(\n query: Query,\n ): {\n args: FunctionArgs<Query>;\n value: undefined | FunctionReturnType<Query>;\n }[] {\n const queriesWithName: {\n args: FunctionArgs<Query>;\n value: undefined | FunctionReturnType<Query>;\n }[] = [];\n const name = getFunctionName(query);\n for (const queryResult of this.queryResults.values()) {\n if (queryResult.udfPath === canonicalizeUdfPath(name)) {\n queriesWithName.push({\n args: queryResult.args as FunctionArgs<Query>,\n value: OptimisticLocalStoreImpl.queryValue(queryResult.result),\n });\n }\n }\n return queriesWithName;\n }\n\n setQuery<QueryReference extends FunctionReference<\"query\">>(\n queryReference: QueryReference,\n args: FunctionArgs<QueryReference>,\n value: undefined | FunctionReturnType<QueryReference>,\n ): void {\n const queryArgs = parseArgs(args);\n const name = getFunctionName(queryReference);\n const queryToken = serializePathAndArgs(name, queryArgs);\n\n let result: FunctionResult | undefined;\n if (value === undefined) {\n result = undefined;\n } else {\n result = {\n success: true,\n value,\n // It's an optimistic update, so there are no function logs to show.\n logLines: [],\n };\n }\n const query: Query = {\n udfPath: name,\n args: queryArgs,\n result,\n };\n this.queryResults.set(queryToken, query);\n this.modifiedQueries.push(queryToken);\n }\n\n private static queryValue(\n result: FunctionResult | undefined,\n ): Value | undefined {\n if (result === undefined) {\n return undefined;\n } else if (result.success) {\n return result.value;\n } else {\n // If the query is an error state, just return `undefined` as though\n // it's loading. Optimistic updates should already handle `undefined` well\n // and there isn't a need to break the whole update because it tried\n // to load a single query that errored.\n return undefined;\n }\n }\n}\n\ntype OptimisticUpdateAndId = {\n update: WrappedOptimisticUpdate;\n mutationId: RequestId;\n};\n\ntype Query = {\n // undefined means the query was set to be loading (undefined) in an optimistic update.\n // Note that we can also have queries not present in the QueryResultMap\n // at all because they are still loading from the server and have no optimistic update\n // setting an optimistic value in advance.\n result: FunctionResult | undefined;\n udfPath: string;\n args: Record<string, Value>;\n};\nexport type QueryResultsMap = Map<QueryToken, Query>;\n\ntype ChangedQueries = QueryToken[];\n\n/**\n * A view of all of our query results with optimistic updates applied on top.\n */\nexport class OptimisticQueryResults {\n private queryResults: QueryResultsMap;\n private optimisticUpdates: OptimisticUpdateAndId[];\n\n constructor() {\n this.queryResults = new Map();\n this.optimisticUpdates = [];\n }\n\n /**\n * Apply all optimistic updates on top of server query results\n */\n ingestQueryResultsFromServer(\n serverQueryResults: QueryResultsMap,\n optimisticUpdatesToDrop: Set<RequestId>,\n ): ChangedQueries {\n this.optimisticUpdates = this.optimisticUpdates.filter((updateAndId) => {\n return !optimisticUpdatesToDrop.has(updateAndId.mutationId);\n });\n\n const oldQueryResults = this.queryResults;\n this.queryResults = new Map(serverQueryResults);\n const localStore = new OptimisticLocalStoreImpl(this.queryResults);\n for (const updateAndId of this.optimisticUpdates) {\n updateAndId.update(localStore);\n }\n\n // To find the changed queries, just do a shallow comparison\n // TODO(CX-733): Change this so we avoid unnecessary rerenders\n const changedQueries: ChangedQueries = [];\n for (const [queryToken, query] of this.queryResults) {\n const oldQuery = oldQueryResults.get(queryToken);\n if (oldQuery === undefined || oldQuery.result !== query.result) {\n changedQueries.push(queryToken);\n }\n }\n\n return changedQueries;\n }\n\n applyOptimisticUpdate(\n update: WrappedOptimisticUpdate,\n mutationId: RequestId,\n ): ChangedQueries {\n // Apply the update to our store\n this.optimisticUpdates.push({\n update,\n mutationId,\n });\n const localStore = new OptimisticLocalStoreImpl(this.queryResults);\n update(localStore);\n\n // Notify about any query results that changed\n // TODO(CX-733): Change this so we avoid unnecessary rerenders\n return localStore.modifiedQueries;\n }\n\n /**\n * \"Raw\" with respect to errors vs values, but query results still have\n * optimistic updates applied.\n *\n * @internal\n */\n rawQueryResult(queryToken: QueryToken): FunctionResult | undefined {\n const query = this.queryResults.get(queryToken);\n if (query === undefined) {\n return undefined;\n }\n return query.result;\n }\n\n queryResult(queryToken: QueryToken): Value | undefined {\n const query = this.queryResults.get(queryToken);\n if (query === undefined) {\n return undefined;\n }\n const result = query.result;\n if (result === undefined) {\n return undefined;\n } else if (result.success) {\n return result.value;\n } else {\n if (result.errorData !== undefined) {\n throw forwardData(\n result,\n new ConvexError(\n createHybridErrorStacktrace(\"query\", query.udfPath, result),\n ),\n );\n }\n throw new Error(\n createHybridErrorStacktrace(\"query\", query.udfPath, result),\n );\n }\n }\n\n hasQueryResult(queryToken: QueryToken): boolean {\n return this.queryResults.get(queryToken) !== undefined;\n }\n\n /**\n * @internal\n */\n queryLogs(queryToken: QueryToken): string[] | undefined {\n const query = this.queryResults.get(queryToken);\n return query?.result?.logLines;\n }\n}\n", "// Implements an unsigned long.\n// This is a subset of https://github.com/dcodeIO/Long.js,\n// vendored to decrease bundle size.\n// Copyright Daniel Wirtz <dcode@dcode.io>\n// License: Apache Version 2.0\n/*\n\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright 2023 Daniel Wirtz <dcode@dcode.io>\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n// This works... but don't try to compare one to a real Long.js Long!\n// For internal use only.\n// `| 0` assures the runtime that we are using integer arithmetic\nexport class Long {\n low: number;\n high: number;\n __isUnsignedLong__: boolean;\n\n static isLong(obj: Long) {\n return (obj && obj.__isUnsignedLong__) === true;\n }\n\n constructor(low: number, high: number) {\n this.low = low | 0;\n this.high = high | 0;\n this.__isUnsignedLong__ = true;\n }\n\n // prettier-ignore\n static fromBytesLE(bytes: number[]): Long {\n return new Long(\n bytes[0] |\n bytes[1] << 8 |\n bytes[2] << 16 |\n bytes[3] << 24,\n bytes[4] |\n bytes[5] << 8 |\n bytes[6] << 16 |\n bytes[7] << 24,\n );\n }\n\n // prettier-ignore\n toBytesLE() {\n const hi = this.high;\n const lo = this.low;\n return [\n lo & 0xff,\n lo >>> 8 & 0xff,\n lo >>> 16 & 0xff,\n lo >>> 24,\n hi & 0xff,\n hi >>> 8 & 0xff,\n hi >>> 16 & 0xff,\n hi >>> 24\n ];\n }\n\n static fromNumber(value: number) {\n if (isNaN(value)) return UZERO;\n if (value < 0) return UZERO;\n if (value >= TWO_PWR_64_DBL) return MAX_UNSIGNED_VALUE;\n return new Long(value % TWO_PWR_32_DBL | 0, (value / TWO_PWR_32_DBL) | 0);\n }\n\n toString() {\n return (\n BigInt(this.high) * BigInt(TWO_PWR_32_DBL) +\n BigInt(this.low)\n ).toString();\n }\n\n equals(other: Long) {\n if (!Long.isLong(other)) other = Long.fromValue(other);\n if (this.high >>> 31 === 1 && other.high >>> 31 === 1) return false;\n return this.high === other.high && this.low === other.low;\n }\n\n notEquals(other: Long) {\n return !this.equals(other);\n }\n\n comp(other: Long) {\n if (!Long.isLong(other)) other = Long.fromValue(other);\n if (this.equals(other)) return 0;\n return other.high >>> 0 > this.high >>> 0 ||\n (other.high === this.high && other.low >>> 0 > this.low >>> 0)\n ? -1\n : 1;\n }\n\n lessThanOrEqual(other: Long) {\n return this.comp(/* validates */ other) <= 0;\n }\n\n static fromValue(val: any) {\n if (typeof val === \"number\") return Long.fromNumber(val);\n // Throws for non-objects, converts non-instanceof Long:\n return new Long(val.low, val.high);\n }\n}\n\nconst UZERO = new Long(0, 0);\nconst TWO_PWR_16_DBL = 1 << 16;\nconst TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;\nconst TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;\nconst MAX_UNSIGNED_VALUE = new Long(0xffffffff | 0, 0xffffffff | 0);\n", "import { jsonToConvex } from \"../../values/index.js\";\nimport { Long } from \"../../vendor/long.js\";\nimport { logForFunction, Logger } from \"../logging.js\";\nimport { QueryId, StateVersion, Transition } from \"./protocol.js\";\nimport { FunctionResult } from \"./function_result.js\";\n\n/**\n * A represention of the query results we've received on the current WebSocket\n * connection.\n *\n * Queries you won't find here include:\n * - queries which have been requested, but no query transition has been received yet for\n * - queries which are populated only though active optimistic updates, but are not subscribed to\n * - queries which have already been removed by the server (which it shouldn't do unless that's\n * been requested by the client)\n */\nexport class RemoteQuerySet {\n private version: StateVersion;\n private readonly remoteQuerySet: Map<QueryId, FunctionResult>;\n private readonly queryPath: (queryId: QueryId) => string | null;\n private readonly logger: Logger;\n\n constructor(queryPath: (queryId: QueryId) => string | null, logger: Logger) {\n this.version = { querySet: 0, ts: Long.fromNumber(0), identity: 0 };\n this.remoteQuerySet = new Map();\n this.queryPath = queryPath;\n this.logger = logger;\n }\n\n transition(transition: Transition): void {\n const start = transition.startVersion;\n if (\n this.version.querySet !== start.querySet ||\n this.version.ts.notEquals(start.ts) ||\n this.version.identity !== start.identity\n ) {\n throw new Error(\n `Invalid start version: ${start.ts.toString()}:${start.querySet}:${start.identity}, transitioning from ${this.version.ts.toString()}:${this.version.querySet}:${this.version.identity}`,\n );\n }\n for (const modification of transition.modifications) {\n switch (modification.type) {\n case \"QueryUpdated\": {\n const queryPath = this.queryPath(modification.queryId);\n if (queryPath) {\n for (const line of modification.logLines) {\n logForFunction(this.logger, \"info\", \"query\", queryPath, line);\n }\n }\n const value = jsonToConvex(modification.value ?? null);\n this.remoteQuerySet.set(modification.queryId, {\n success: true,\n value,\n logLines: modification.logLines,\n });\n break;\n }\n case \"QueryFailed\": {\n const queryPath = this.queryPath(modification.queryId);\n if (queryPath) {\n for (const line of modification.logLines) {\n logForFunction(this.logger, \"info\", \"query\", queryPath, line);\n }\n }\n const { errorData } = modification;\n this.remoteQuerySet.set(modification.queryId, {\n success: false,\n errorMessage: modification.errorMessage,\n errorData:\n errorData !== undefined ? jsonToConvex(errorData) : undefined,\n logLines: modification.logLines,\n });\n break;\n }\n case \"QueryRemoved\": {\n this.remoteQuerySet.delete(modification.queryId);\n break;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n modification satisfies never;\n throw new Error(`Invalid modification ${(modification as any).type}`);\n }\n }\n }\n this.version = transition.endVersion;\n }\n\n remoteQueryResults(): Map<QueryId, FunctionResult> {\n return this.remoteQuerySet;\n }\n\n timestamp(): Long {\n return this.version.ts;\n }\n}\n", "import type { UserIdentityAttributes } from \"../../server/authentication.js\";\nexport type { UserIdentityAttributes } from \"../../server/authentication.js\";\nimport { JSONValue, Base64 } from \"../../values/index.js\";\nimport { Long } from \"../../vendor/long.js\";\n\n/**\n * Shared schema\n */\n\nexport function u64ToLong(encoded: EncodedU64): U64 {\n const integerBytes = Base64.toByteArray(encoded);\n return Long.fromBytesLE(Array.from(integerBytes));\n}\n\nexport function longToU64(raw: U64): EncodedU64 {\n const integerBytes = new Uint8Array(raw.toBytesLE());\n return Base64.fromByteArray(integerBytes);\n}\n\nexport function parseServerMessage(\n encoded: EncodedServerMessage,\n): WireServerMessage {\n switch (encoded.type) {\n case \"FatalError\":\n case \"AuthError\":\n case \"ActionResponse\":\n case \"TransitionChunk\":\n case \"Ping\": {\n return { ...encoded };\n }\n case \"MutationResponse\": {\n if (encoded.success) {\n return { ...encoded, ts: u64ToLong(encoded.ts) };\n } else {\n return { ...encoded };\n }\n }\n case \"Transition\": {\n return {\n ...encoded,\n startVersion: {\n ...encoded.startVersion,\n ts: u64ToLong(encoded.startVersion.ts),\n },\n endVersion: {\n ...encoded.endVersion,\n ts: u64ToLong(encoded.endVersion.ts),\n },\n };\n }\n default: {\n encoded satisfies never;\n }\n }\n return undefined as never;\n}\n\nexport function encodeClientMessage(\n message: ClientMessage,\n): EncodedClientMessage {\n switch (message.type) {\n case \"Authenticate\":\n case \"ModifyQuerySet\":\n case \"Mutation\":\n case \"Action\":\n case \"Event\": {\n return { ...message };\n }\n case \"Connect\": {\n if (message.maxObservedTimestamp !== undefined) {\n return {\n ...message,\n maxObservedTimestamp: longToU64(message.maxObservedTimestamp),\n };\n } else {\n return { ...message, maxObservedTimestamp: undefined };\n }\n }\n default: {\n message satisfies never;\n }\n }\n return undefined as never;\n}\n\ntype U64 = Long;\ntype EncodedU64 = string;\n\n/**\n * Unique nonnegative integer identifying a single query.\n */\nexport type QueryId = number; // nonnegative int\n\nexport type QuerySetVersion = number; // nonnegative int\n\nexport type RequestId = number; // nonnegative int\n\nexport type IdentityVersion = number; // nonnegative int\n\n/**\n * A serialized representation of decisions made during a query's execution.\n *\n * A journal is produced when a query function first executes and is re-used\n * when a query is re-executed.\n *\n * Currently this is used to store pagination end cursors to ensure\n * that pages of paginated queries will always end at the same cursor. This\n * enables gapless, reactive pagination.\n *\n * `null` is used to represent empty journals.\n * @public\n */\nexport type QueryJournal = string | null;\n\n/**\n * Client message schema\n */\n\ntype Connect = {\n type: \"Connect\";\n sessionId: string;\n connectionCount: number;\n lastCloseReason: string | null;\n maxObservedTimestamp?: TS | undefined;\n clientTs: number;\n};\n\nexport type AddQuery = {\n type: \"Add\";\n queryId: QueryId;\n udfPath: string;\n args: JSONValue[];\n journal?: QueryJournal | undefined;\n /**\n * @internal\n */\n componentPath?: string | undefined;\n};\n\nexport type RemoveQuery = {\n type: \"Remove\";\n queryId: QueryId;\n};\n\nexport type QuerySetModification = {\n type: \"ModifyQuerySet\";\n baseVersion: QuerySetVersion;\n newVersion: QuerySetVersion;\n modifications: (AddQuery | RemoveQuery)[];\n};\n\nexport type MutationRequest = {\n type: \"Mutation\";\n requestId: RequestId;\n udfPath: string;\n args: JSONValue[];\n // Execute the mutation on a specific component.\n // Only admin auth is allowed to run mutations on non-root components.\n componentPath?: string | undefined;\n};\n\nexport type ActionRequest = {\n type: \"Action\";\n requestId: RequestId;\n udfPath: string;\n args: JSONValue[];\n // Execute the action on a specific component.\n // Only admin auth is allowed to run actions on non-root components.\n componentPath?: string | undefined;\n};\n\nexport type AdminAuthentication = {\n type: \"Authenticate\";\n tokenType: \"Admin\";\n value: string;\n baseVersion: IdentityVersion;\n impersonating?: UserIdentityAttributes | undefined;\n};\n\nexport type Authenticate =\n | AdminAuthentication\n | {\n type: \"Authenticate\";\n tokenType: \"User\";\n value: string;\n baseVersion: IdentityVersion;\n }\n | {\n type: \"Authenticate\";\n tokenType: \"None\";\n baseVersion: IdentityVersion;\n };\n\nexport type Event = {\n type: \"Event\";\n eventType: string;\n event: any;\n};\nexport type ClientMessage =\n | Connect\n | Authenticate\n | QuerySetModification\n | MutationRequest\n | ActionRequest\n | Event;\n\ntype EncodedConnect = Omit<Connect, \"maxObservedTimestamp\"> & {\n maxObservedTimestamp?: EncodedTS | undefined;\n};\n\n// It's not a big deal to add `| undefined` to any optional properties here because\n// these messages are bound for JSON.stringify() serialization, which removes properties\n// that are undefined.\ntype EncodedClientMessage =\n | EncodedConnect\n | Authenticate\n | QuerySetModification\n | MutationRequest\n | ActionRequest\n | Event;\n\n/**\n * Server message schema\n */\nexport type TS = U64;\ntype EncodedTS = EncodedU64;\ntype LogLines = string[];\n\nexport type StateVersion = {\n querySet: QuerySetVersion;\n ts: TS;\n identity: IdentityVersion;\n};\ntype EncodedStateVersion = Omit<StateVersion, \"ts\"> & { ts: EncodedTS };\n\ntype StateModification =\n | {\n type: \"QueryUpdated\";\n queryId: QueryId;\n value: JSONValue;\n logLines: LogLines;\n journal: QueryJournal;\n }\n | {\n type: \"QueryFailed\";\n queryId: QueryId;\n errorMessage: string;\n logLines: LogLines;\n errorData: JSONValue;\n journal: QueryJournal;\n }\n | {\n type: \"QueryRemoved\";\n queryId: QueryId;\n };\n\nexport type Transition = {\n type: \"Transition\";\n startVersion: StateVersion;\n endVersion: StateVersion;\n modifications: StateModification[];\n clientClockSkew?: number;\n serverTs?: number;\n};\n\nexport type TransitionChunk = {\n type: \"TransitionChunk\";\n chunk: string;\n partNumber: number;\n totalParts: number;\n transitionId: string;\n};\n\ntype MutationSuccess = {\n type: \"MutationResponse\";\n requestId: RequestId;\n success: true;\n result: JSONValue;\n ts: TS;\n logLines: LogLines;\n};\ntype MutationFailed = {\n type: \"MutationResponse\";\n requestId: RequestId;\n success: false;\n result: string;\n logLines: LogLines;\n errorData?: JSONValue;\n};\nexport type MutationResponse = MutationSuccess | MutationFailed;\ntype ActionSuccess = {\n type: \"ActionResponse\";\n requestId: RequestId;\n success: true;\n result: JSONValue;\n logLines: LogLines;\n};\ntype ActionFailed = {\n type: \"ActionResponse\";\n requestId: RequestId;\n success: false;\n result: string;\n logLines: LogLines;\n errorData?: JSONValue;\n};\nexport type ActionResponse = ActionSuccess | ActionFailed;\nexport type AuthError = {\n type: \"AuthError\";\n error: string;\n baseVersion: IdentityVersion;\n // True if this error is in response to processing a new `Authenticate` message.\n // Other AuthErrors may occur due to executing a function with expired auth and\n // should be handled differently.\n authUpdateAttempted: boolean;\n};\ntype FatalError = {\n type: \"FatalError\";\n error: string;\n};\ntype Ping = {\n type: \"Ping\";\n};\n\n// Server Messages without the messages only visible to WebSocketManager\nexport type ServerMessage =\n | Transition\n | MutationResponse\n | ActionResponse\n | FatalError\n | AuthError;\n\nexport type WireServerMessage =\n | Transition\n | TransitionChunk\n | MutationResponse\n | ActionResponse\n | FatalError\n | AuthError\n | Ping;\n\ntype EncodedTransition = Omit<Transition, \"startVersion\" | \"endVersion\"> & {\n startVersion: EncodedStateVersion;\n endVersion: EncodedStateVersion;\n};\ntype EncodedMutationSuccess = Omit<MutationSuccess, \"ts\"> & { ts: EncodedTS };\ntype EncodedMutationResponse = MutationFailed | EncodedMutationSuccess;\n\ntype EncodedServerMessage =\n | EncodedTransition\n | TransitionChunk\n | EncodedMutationResponse\n | ActionResponse\n | FatalError\n | AuthError\n | Ping;\n", "import { Logger } from \"../logging.js\";\nimport {\n ClientMessage,\n encodeClientMessage,\n parseServerMessage,\n ServerMessage,\n Transition,\n TransitionChunk,\n} from \"./protocol.js\";\n\nconst CLOSE_NORMAL = 1000;\nconst CLOSE_GOING_AWAY = 1001;\nconst CLOSE_NO_STATUS = 1005;\n/** Convex-specific close code representing a \"404 Not Found\".\n * The edge Onramp accepts websocket upgrades before confirming that the\n * intended destination exists, so this code is sent once we've discovered that\n * the destination does not exist.\n */\nconst CLOSE_NOT_FOUND = 4040;\n\n/**\n * The various states our WebSocket can be in:\n *\n * - \"disconnected\": We don't have a WebSocket, but plan to create one.\n * - \"connecting\": We have created the WebSocket and are waiting for the\n * `onOpen` callback.\n * - \"ready\": We have an open WebSocket.\n * - \"stopped\": The WebSocket was closed and a new one can be created via `.restart()`.\n * - \"terminated\": We have closed the WebSocket and will never create a new one.\n *\n *\n * WebSocket State Machine\n * -----------------------\n * initialState: disconnected\n * validTransitions:\n * disconnected:\n * new WebSocket() -> connecting\n * terminate() -> terminated\n * connecting:\n * onopen -> ready\n * close() -> disconnected\n * terminate() -> terminated\n * ready:\n * close() -> disconnected\n * stop() -> stopped\n * terminate() -> terminated\n * stopped:\n * restart() -> connecting\n * terminate() -> terminated\n * terminalStates:\n * terminated\n *\n *\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u250C\u2500\u2500\u2500\u2500terminate()\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 disconnected \u2502\u25C0\u2500\u2510\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u25BC \u2502 \u25B2 \u2502\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 new WebSocket() \u2502 \u2502\n * \u250C\u2500\u25B6\u2502 terminated \u2502\u25C0\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2502 \u2502 \u2502\n * \u2502 \u25B2 terminate() \u2502 close() close()\n * \u2502 terminate() \u2502 \u2502 \u2502 \u2502\n * \u2502 \u2502 \u2502 \u25BC \u2502 \u2502\n * \u2502 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n * \u2502 \u2502 stopped \u2502\u2500\u2500restart()\u2500\u2500\u2500\u25B6\u2502 connecting \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u2502 \u25B2 \u2502 \u2502\n * \u2502 \u2502 onopen \u2502\n * \u2502 \u2502 \u2502 \u2502\n * \u2502 \u2502 \u25BC \u2502\n * terminate() \u2502 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500stop()\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 ready \u2502\u2500\u2500\u2518\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * \u2502 \u2502\n * \u2502 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * The `connecting` and `ready` state have a sub-state-machine for pausing.\n */\n\ntype Socket =\n | { state: \"disconnected\" }\n | { state: \"connecting\"; ws: WebSocket; paused: \"yes\" | \"no\" }\n | { state: \"ready\"; ws: WebSocket; paused: \"yes\" | \"no\" | \"uninitialized\" }\n | { state: \"stopped\" }\n | { state: \"terminated\" };\n\nexport type ReconnectMetadata = {\n connectionCount: number;\n lastCloseReason: string | null;\n clientTs: number;\n};\n\nexport type OnMessageResponse = {\n hasSyncedPastLastReconnect: boolean;\n};\n\nlet firstTime: number | undefined;\nfunction monotonicMillis() {\n if (firstTime === undefined) {\n firstTime = Date.now();\n }\n if (typeof performance === \"undefined\" || !performance.now) {\n return Date.now();\n }\n return Math.round(firstTime + performance.now());\n}\n\nfunction prettyNow() {\n return `t=${Math.round((monotonicMillis() - firstTime!) / 100) / 10}s`;\n}\n\nconst serverDisconnectErrors = {\n // A known error, e.g. during a restart or push\n InternalServerError: { timeout: 1000 },\n // ErrorMetadata::overloaded() messages that we realy should back off\n SubscriptionsWorkerFullError: { timeout: 3000 },\n TooManyConcurrentRequests: { timeout: 3000 },\n CommitterFullError: { timeout: 3000 },\n AwsTooManyRequestsException: { timeout: 3000 },\n ExecuteFullError: { timeout: 3000 },\n SystemTimeoutError: { timeout: 3000 },\n ExpiredInQueue: { timeout: 3000 },\n // ErrorMetadata::feature_temporarily_unavailable() that typically indicate a deploy just happened\n VectorIndexesUnavailable: { timeout: 1000 },\n SearchIndexesUnavailable: { timeout: 1000 },\n TableSummariesUnavailable: { timeout: 1000 },\n // ErrorMetadata::service_unavailable() when backend/conductor is unreachable\n ServiceUnavailable: { timeout: 3000 },\n // ErrorMetadata::rejected_before_execution() when funrun workers are unavailable\n WorkerOverloaded: { timeout: 3000 },\n IsolateNotClean: { timeout: 3000 },\n InitialPermitTimeoutError: { timeout: 3000 },\n // More ErrorMetadata::overloaded()\n VectorIndexTooLarge: { timeout: 3000 },\n SearchIndexTooLarge: { timeout: 3000 },\n TooManyWritesInTimePeriod: { timeout: 3000 },\n} as const satisfies Record<string, { timeout: number }>;\n\ntype ServerDisconnectError = keyof typeof serverDisconnectErrors | \"Unknown\";\n\nfunction classifyDisconnectError(s?: string): ServerDisconnectError {\n if (s === undefined) return \"Unknown\";\n // startsWith so more info could be at the end (although currently there isn't)\n\n for (const prefix of Object.keys(\n serverDisconnectErrors,\n ) as ServerDisconnectError[]) {\n if (s.startsWith(prefix)) {\n return prefix;\n }\n }\n return \"Unknown\";\n}\n\n/**\n * A wrapper around a websocket that handles errors, reconnection, and message\n * parsing.\n */\nexport class WebSocketManager {\n private socket: Socket;\n\n private connectionCount: number;\n private _hasEverConnected: boolean = false;\n private lastCloseReason:\n | \"InitialConnect\"\n | \"OnCloseInvoked\"\n | (string & {}) // a full serverErrorReason (not just the prefix) or a new one\n | null;\n\n // State for assembling the split-up Transition currently being received.\n private transitionChunkBuffer: {\n chunks: string[];\n totalParts: number;\n transitionId: string;\n } | null = null;\n\n /** Upon HTTPS/WSS failure, the first jittered backoff duration, in ms. */\n private readonly defaultInitialBackoff: number;\n\n /** We backoff exponentially, but we need to cap that--this is the jittered max. */\n private readonly maxBackoff: number;\n\n /** How many times have we failed consecutively? */\n private retries: number;\n\n /** How long before lack of server response causes us to initiate a reconnect,\n * in ms */\n private readonly serverInactivityThreshold: number;\n\n private reconnectDueToServerInactivityTimeout: ReturnType<\n typeof setTimeout\n > | null;\n\n /** Scheduled reconnect state: timeout handle and timing info */\n private scheduledReconnect: {\n timeout: ReturnType<typeof setTimeout>;\n scheduledAt: number;\n backoffMs: number;\n } | null = null;\n\n private networkOnlineHandler: (() => void) | null = null;\n\n /** Pending event to send after reconnecting due to network recovery */\n private pendingNetworkRecoveryInfo: { timeSavedMs: number } | null = null;\n\n private readonly uri: string;\n private readonly onOpen: (reconnectMetadata: ReconnectMetadata) => void;\n private readonly onResume: () => void;\n private readonly onMessage: (message: ServerMessage) => OnMessageResponse;\n private readonly webSocketConstructor: typeof WebSocket;\n private readonly logger: Logger;\n private readonly onServerDisconnectError:\n | ((message: string) => void)\n | undefined;\n\n constructor(\n uri: string,\n callbacks: {\n onOpen: (reconnectMetadata: ReconnectMetadata) => void;\n onResume: () => void;\n onMessage: (message: ServerMessage) => OnMessageResponse;\n onServerDisconnectError?: ((message: string) => void) | undefined;\n },\n webSocketConstructor: typeof WebSocket,\n logger: Logger,\n private readonly markConnectionStateDirty: () => void,\n private readonly debug: boolean,\n ) {\n this.webSocketConstructor = webSocketConstructor;\n this.socket = { state: \"disconnected\" };\n this.connectionCount = 0;\n this.lastCloseReason = \"InitialConnect\";\n\n // backoff for unknown errors\n this.defaultInitialBackoff = 1000;\n this.maxBackoff = 64000;\n this.retries = 0;\n\n // Ping messages (sync protocol Pings, not WebSocket protocol Pings) are\n // sent every 15s in the absence of other messages. But a single large\n // Transition or other downstream message can hog the line so this\n // threshold is set higher to prevent clients from giving up.\n this.serverInactivityThreshold = 60000;\n this.reconnectDueToServerInactivityTimeout = null;\n\n this.uri = uri;\n this.onOpen = callbacks.onOpen;\n this.onResume = callbacks.onResume;\n this.onMessage = callbacks.onMessage;\n this.onServerDisconnectError = callbacks.onServerDisconnectError;\n this.logger = logger;\n\n // Set up network online event listener\n this.setupNetworkListener();\n\n this.connect();\n }\n\n private setSocketState(state: Socket) {\n this.socket = state;\n this._logVerbose(\n `socket state changed: ${this.socket.state}, paused: ${\n \"paused\" in this.socket ? this.socket.paused : undefined\n }`,\n );\n this.markConnectionStateDirty();\n }\n\n private setupNetworkListener() {\n // Only set up listener if we're in a browser environment with addEventListener\n // (React Native has window but not addEventListener)\n if (\n typeof window === \"undefined\" ||\n typeof window.addEventListener !== \"function\"\n ) {\n return;\n }\n // Avoid registering duplicate listeners\n if (this.networkOnlineHandler !== null) {\n return;\n }\n\n this.networkOnlineHandler = () => {\n this._logVerbose(\"network online event detected\");\n this.tryReconnectImmediately();\n };\n\n window.addEventListener(\"online\", this.networkOnlineHandler);\n this._logVerbose(\"network online event listener registered\");\n }\n\n private cleanupNetworkListener() {\n if (\n this.networkOnlineHandler &&\n typeof window !== \"undefined\" &&\n typeof window.removeEventListener === \"function\"\n ) {\n window.removeEventListener(\"online\", this.networkOnlineHandler);\n this.networkOnlineHandler = null;\n this._logVerbose(\"network online event listener removed\");\n }\n }\n\n private assembleTransition(chunk: TransitionChunk): Transition | null {\n if (\n chunk.partNumber < 0 ||\n chunk.partNumber >= chunk.totalParts ||\n chunk.totalParts === 0 ||\n (this.transitionChunkBuffer &&\n (this.transitionChunkBuffer.totalParts !== chunk.totalParts ||\n this.transitionChunkBuffer.transitionId !== chunk.transitionId))\n ) {\n // Throwing an error doesn't crash the client, so clear the buffer.\n this.transitionChunkBuffer = null;\n throw new Error(\"Invalid TransitionChunk\");\n }\n\n if (this.transitionChunkBuffer === null) {\n this.transitionChunkBuffer = {\n chunks: [],\n totalParts: chunk.totalParts,\n transitionId: chunk.transitionId,\n };\n }\n\n if (chunk.partNumber !== this.transitionChunkBuffer.chunks.length) {\n // Throwing an error doesn't crash the client, so clear the buffer.\n const expectedLength = this.transitionChunkBuffer.chunks.length;\n this.transitionChunkBuffer = null;\n throw new Error(\n `TransitionChunk received out of order: expected part ${expectedLength}, got ${chunk.partNumber}`,\n );\n }\n\n this.transitionChunkBuffer.chunks.push(chunk.chunk);\n\n if (this.transitionChunkBuffer.chunks.length === chunk.totalParts) {\n const fullJson = this.transitionChunkBuffer.chunks.join(\"\");\n this.transitionChunkBuffer = null;\n\n const transition = parseServerMessage(JSON.parse(fullJson));\n if (transition.type !== \"Transition\") {\n throw new Error(\n `Expected Transition, got ${transition.type} after assembling chunks`,\n );\n }\n return transition;\n }\n\n return null;\n }\n\n private connect() {\n if (this.socket.state === \"terminated\") {\n return;\n }\n if (\n this.socket.state !== \"disconnected\" &&\n this.socket.state !== \"stopped\"\n ) {\n throw new Error(\n \"Didn't start connection from disconnected state: \" + this.socket.state,\n );\n }\n\n const ws = new this.webSocketConstructor(this.uri);\n this._logVerbose(\"constructed WebSocket\");\n this.setSocketState({\n state: \"connecting\",\n ws,\n paused: \"no\",\n });\n\n // Kick off server inactivity timer before WebSocket connection is established\n // so we can detect cases where handshake fails.\n // The `onopen` event only fires after the connection is established:\n // Source: https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\n this.resetServerInactivityTimeout();\n\n ws.onopen = () => {\n this.logger.logVerbose(\"begin ws.onopen\");\n if (this.socket.state !== \"connecting\") {\n throw new Error(\"onopen called with socket not in connecting state\");\n }\n this.setSocketState({\n state: \"ready\",\n ws,\n paused: this.socket.paused === \"yes\" ? \"uninitialized\" : \"no\",\n });\n this.resetServerInactivityTimeout();\n if (this.socket.paused === \"no\") {\n this._hasEverConnected = true;\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n clientTs: monotonicMillis(),\n });\n }\n\n if (this.lastCloseReason !== \"InitialConnect\") {\n if (this.lastCloseReason) {\n this.logger.log(\n \"WebSocket reconnected at\",\n prettyNow(),\n \"after disconnect due to\",\n this.lastCloseReason,\n );\n } else {\n this.logger.log(\"WebSocket reconnected at\", prettyNow());\n }\n }\n\n this.connectionCount += 1;\n this.lastCloseReason = null;\n\n // Send event for network recovery reconnect if applicable\n if (this.pendingNetworkRecoveryInfo !== null) {\n const { timeSavedMs } = this.pendingNetworkRecoveryInfo;\n this.pendingNetworkRecoveryInfo = null;\n this.sendMessage({\n type: \"Event\",\n eventType: \"NetworkRecoveryReconnect\",\n event: { timeSavedMs },\n });\n this.logger.log(\n `Network recovery reconnect saved ~${Math.round(timeSavedMs / 1000)}s of waiting`,\n );\n }\n };\n // NB: The WebSocket API calls `onclose` even if connection fails, so we can route all error paths through `onclose`.\n ws.onerror = (error) => {\n this.transitionChunkBuffer = null;\n const message = (error as ErrorEvent).message;\n if (message) {\n this.logger.log(`WebSocket error message: ${message}`);\n }\n };\n ws.onmessage = (message) => {\n this.resetServerInactivityTimeout();\n const messageLength = message.data.length;\n let serverMessage = parseServerMessage(JSON.parse(message.data));\n this._logVerbose(`received ws message with type ${serverMessage.type}`);\n\n // Ping's only purpose is to reset the server inactivity timer.\n if (serverMessage.type === \"Ping\") {\n return;\n }\n\n // TransitionChunks never reach the main client logic.\n if (serverMessage.type === \"TransitionChunk\") {\n const transition = this.assembleTransition(serverMessage);\n if (!transition) {\n return;\n }\n serverMessage = transition;\n this._logVerbose(\n `assembled full ws message of type ${serverMessage.type}`,\n );\n }\n\n if (this.transitionChunkBuffer !== null) {\n this.transitionChunkBuffer = null;\n this.logger.log(\n `Received unexpected ${serverMessage.type} while buffering TransitionChunks`,\n );\n }\n\n if (serverMessage.type === \"Transition\") {\n this.reportLargeTransition({\n messageLength,\n transition: serverMessage,\n });\n }\n const response = this.onMessage(serverMessage);\n if (response.hasSyncedPastLastReconnect) {\n // Reset backoff to 0 once all outstanding requests are complete.\n this.retries = 0;\n this.markConnectionStateDirty();\n }\n };\n ws.onclose = (event) => {\n this._logVerbose(\"begin ws.onclose\");\n this.transitionChunkBuffer = null;\n if (this.lastCloseReason === null) {\n // event.reason is often an empty string\n this.lastCloseReason = event.reason || `closed with code ${event.code}`;\n }\n if (\n event.code !== CLOSE_NORMAL &&\n event.code !== CLOSE_GOING_AWAY && // This commonly gets fired on mobile apps when the app is backgrounded\n event.code !== CLOSE_NO_STATUS &&\n event.code !== CLOSE_NOT_FOUND // Note that we want to retry on a 404, as it can be transient during a push.\n ) {\n let msg = `WebSocket closed with code ${event.code}`;\n if (event.reason) {\n msg += `: ${event.reason}`;\n }\n this.logger.log(msg);\n if (this.onServerDisconnectError && event.reason) {\n // This callback is a unstable API, InternalServerErrors in particular may be removed\n // since they reflect expected temporary downtime. But until a quantitative measure\n // of uptime is reported this unstable API errs on the inclusive side.\n this.onServerDisconnectError(msg);\n }\n }\n const reason = classifyDisconnectError(event.reason);\n this.scheduleReconnect(reason);\n return;\n };\n }\n\n /**\n * @returns The state of the {@link Socket}.\n */\n socketState(): string {\n return this.socket.state;\n }\n\n /**\n * @param message - A ClientMessage to send.\n * @returns Whether the message (might have been) sent.\n */\n sendMessage(message: ClientMessage) {\n const messageForLog = {\n type: message.type,\n ...(message.type === \"Authenticate\" && message.tokenType === \"User\"\n ? {\n value: `...${message.value.slice(-7)}`,\n }\n : {}),\n };\n if (this.socket.state === \"ready\" && this.socket.paused === \"no\") {\n const encodedMessage = encodeClientMessage(message);\n const request = JSON.stringify(encodedMessage);\n let sent = false;\n try {\n this.socket.ws.send(request);\n sent = true;\n } catch (error: any) {\n this.logger.log(\n `Failed to send message on WebSocket, reconnecting: ${error}`,\n );\n this.closeAndReconnect(\"FailedToSendMessage\");\n }\n this._logVerbose(\n `${sent ? \"sent\" : \"failed to send\"} message with type ${message.type}: ${JSON.stringify(\n messageForLog,\n )}`,\n );\n return true;\n }\n this._logVerbose(\n `message not sent (socket state: ${this.socket.state}, paused: ${\"paused\" in this.socket ? this.socket.paused : undefined}): ${JSON.stringify(\n messageForLog,\n )}`,\n );\n\n return false;\n }\n\n private resetServerInactivityTimeout() {\n if (this.socket.state === \"terminated\") {\n // Don't reset any timers if we were trying to terminate.\n return;\n }\n if (this.reconnectDueToServerInactivityTimeout !== null) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n this.reconnectDueToServerInactivityTimeout = null;\n }\n this.reconnectDueToServerInactivityTimeout = setTimeout(() => {\n this.closeAndReconnect(\"InactiveServer\");\n }, this.serverInactivityThreshold);\n }\n\n private scheduleReconnect(reason: \"client\" | ServerDisconnectError) {\n // Cancel any existing scheduled reconnect to avoid multiple reconnects\n if (this.scheduledReconnect) {\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n }\n\n this.socket = { state: \"disconnected\" };\n const backoff = this.nextBackoff(reason);\n this.markConnectionStateDirty();\n this.logger.log(`Attempting reconnect in ${Math.round(backoff)}ms`);\n\n const scheduledAt = monotonicMillis();\n const timeoutId = setTimeout(() => {\n // Only proceed if this timeout hasn't been cleared\n if (this.scheduledReconnect?.timeout === timeoutId) {\n this.scheduledReconnect = null;\n this.connect();\n }\n }, backoff);\n\n this.scheduledReconnect = {\n timeout: timeoutId,\n scheduledAt,\n backoffMs: backoff,\n };\n }\n\n /**\n * Close the WebSocket and schedule a reconnect.\n *\n * This should be used when we hit an error and would like to restart the session.\n */\n private closeAndReconnect(closeReason: string) {\n this._logVerbose(`begin closeAndReconnect with reason ${closeReason}`);\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n // Nothing to do if we don't have a WebSocket.\n return;\n case \"connecting\":\n case \"ready\": {\n this.lastCloseReason = closeReason;\n // Close the old socket asynchronously, we'll open a new socket in reconnect.\n void this.close();\n this.scheduleReconnect(\"client\");\n return;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n }\n }\n }\n\n /**\n * Close the WebSocket, being careful to clear the onclose handler to avoid re-entrant\n * calls. Use this instead of directly calling `ws.close()`\n *\n * It is the callers responsibility to update the state after this method is called so that the\n * closed socket is not accessible or used again after this method is called\n */\n private close(): Promise<void> {\n this.transitionChunkBuffer = null;\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n // Nothing to do if we don't have a WebSocket.\n return Promise.resolve();\n case \"connecting\": {\n const ws = this.socket.ws;\n // Messages can still be received after close but we're not interested.\n ws.onmessage = (_message) => {\n this._logVerbose(\"Ignoring message received after close\");\n };\n return new Promise((r) => {\n ws.onclose = () => {\n this._logVerbose(\"Closed after connecting\");\n r();\n };\n ws.onopen = () => {\n this._logVerbose(\"Opened after connecting\");\n ws.close();\n };\n });\n }\n case \"ready\": {\n this._logVerbose(\"ws.close called\");\n const ws = this.socket.ws;\n // Messages can still be received after close but we're not interested.\n ws.onmessage = (_message) => {\n this._logVerbose(\"Ignoring message received after close\");\n };\n const result: Promise<void> = new Promise((r) => {\n ws.onclose = () => {\n r();\n };\n });\n ws.close();\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n return Promise.resolve();\n }\n }\n }\n\n /**\n * Close the WebSocket and do not reconnect.\n * @returns A Promise that resolves when the WebSocket `onClose` callback is called.\n */\n terminate(): Promise<void> {\n if (this.reconnectDueToServerInactivityTimeout) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n }\n if (this.scheduledReconnect) {\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n }\n this.cleanupNetworkListener();\n switch (this.socket.state) {\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n case \"connecting\":\n case \"ready\": {\n const result = this.close();\n this.setSocketState({ state: \"terminated\" });\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n throw new Error(\n `Invalid websocket state: ${(this.socket as any).state}`,\n );\n }\n }\n }\n\n stop(): Promise<void> {\n switch (this.socket.state) {\n case \"terminated\":\n // If we're terminating we ignore stop\n return Promise.resolve();\n case \"connecting\":\n case \"stopped\":\n case \"disconnected\":\n case \"ready\": {\n this.cleanupNetworkListener();\n const result = this.close();\n this.socket = { state: \"stopped\" };\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n return Promise.resolve();\n }\n }\n }\n\n /**\n * Create a new WebSocket after a previous `stop()`, unless `terminate()` was\n * called before.\n */\n tryRestart(): void {\n switch (this.socket.state) {\n case \"stopped\":\n break;\n case \"terminated\":\n case \"connecting\":\n case \"ready\":\n case \"disconnected\":\n this.logger.logVerbose(\"Restart called without stopping first\");\n return;\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n }\n }\n this.setupNetworkListener();\n this.connect();\n }\n\n pause(): void {\n switch (this.socket.state) {\n case \"disconnected\":\n case \"stopped\":\n case \"terminated\":\n // If already stopped or stopping ignore.\n return;\n case \"connecting\":\n case \"ready\": {\n this.socket = { ...this.socket, paused: \"yes\" };\n return;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n return;\n }\n }\n }\n\n /**\n * Try to reconnect immediately, canceling any scheduled reconnect.\n * This is useful when detecting network recovery.\n * Only takes action if we're in disconnected state (waiting to reconnect).\n */\n tryReconnectImmediately(): void {\n this._logVerbose(\"tryReconnectImmediately called\");\n\n // Only reconnect if we're in disconnected state (waiting to reconnect)\n if (this.socket.state !== \"disconnected\") {\n this._logVerbose(\n `tryReconnectImmediately called but socket state is ${this.socket.state}, no action taken`,\n );\n return;\n }\n\n // Track how much time we saved by reconnecting immediately\n let timeSavedMs: number | null = null;\n if (this.scheduledReconnect) {\n const elapsed = monotonicMillis() - this.scheduledReconnect.scheduledAt;\n timeSavedMs = Math.max(0, this.scheduledReconnect.backoffMs - elapsed);\n this._logVerbose(\n `would have waited ${Math.round(timeSavedMs)}ms more (backoff was ${Math.round(this.scheduledReconnect.backoffMs)}ms, elapsed ${Math.round(elapsed)}ms)`,\n );\n // Cancel the scheduled reconnect\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n this._logVerbose(\"canceled scheduled reconnect\");\n }\n\n this.logger.log(\"Network recovery detected, reconnecting immediately\");\n // Store the time saved to send as an event after we connect\n this.pendingNetworkRecoveryInfo =\n timeSavedMs !== null ? { timeSavedMs } : null;\n this.connect();\n }\n\n /**\n * Resume the state machine if previously paused.\n */\n resume(): void {\n switch (this.socket.state) {\n case \"connecting\":\n this.socket = { ...this.socket, paused: \"no\" };\n return;\n case \"ready\":\n if (this.socket.paused === \"uninitialized\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n clientTs: monotonicMillis(),\n });\n } else if (this.socket.paused === \"yes\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onResume();\n }\n return;\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n // Ignore resume if not paused, perhaps we already resumed.\n return;\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n }\n }\n this.connect();\n }\n\n connectionState(): {\n isConnected: boolean;\n hasEverConnected: boolean;\n connectionCount: number;\n connectionRetries: number;\n } {\n return {\n isConnected: this.socket.state === \"ready\",\n hasEverConnected: this._hasEverConnected,\n connectionCount: this.connectionCount,\n connectionRetries: this.retries,\n };\n }\n\n private _logVerbose(message: string) {\n this.logger.logVerbose(message);\n }\n\n private nextBackoff(reason: \"client\" | ServerDisconnectError): number {\n const initialBackoff: number =\n reason === \"client\"\n ? 100 // There's no evidence of a server problem, retry quickly\n : reason === \"Unknown\"\n ? this.defaultInitialBackoff\n : serverDisconnectErrors[reason].timeout;\n\n const baseBackoff = initialBackoff * Math.pow(2, this.retries);\n this.retries += 1;\n const actualBackoff = Math.min(baseBackoff, this.maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n }\n\n private reportLargeTransition({\n transition,\n messageLength,\n }: {\n transition: Transition;\n messageLength: number;\n }) {\n if (\n transition.clientClockSkew === undefined ||\n transition.serverTs === undefined\n ) {\n return;\n }\n\n const transitionTransitTime =\n monotonicMillis() - // client time now\n // clientClockSkew = (server time + upstream latency) - client time\n // clientClockSkew is \"how many milliseconds behind (slow) is the client clock\"\n // but the latency of the Connect message inflates this, making it appear further behind\n transition.clientClockSkew -\n transition.serverTs / 1_000_000; // server time when transition was sent\n const prettyTransitionTime = `${Math.round(transitionTransitTime)}ms`;\n const prettyMessageMB = `${Math.round(messageLength / 10_000) / 100}MB`;\n const bytesPerSecond = messageLength / (transitionTransitTime / 1000);\n const prettyBytesPerSecond = `${Math.round(bytesPerSecond / 10_000) / 100}MB per second`;\n this._logVerbose(\n `received ${prettyMessageMB} transition in ${prettyTransitionTime} at ${prettyBytesPerSecond}`,\n );\n\n // Warnings that will show up for *all users*, so don't be too aggressive.\n // These can be silenced (along with reconnection messages) by setting `logger: false` in client options.\n if (messageLength > 20_000_000) {\n // Big enough that the developer should be made aware of this.\n this.logger.log(\n `received query results totaling more that 20MB (${prettyMessageMB}) which will take a long time to download on slower connections`,\n );\n } else if (transitionTransitTime > 20_000) {\n // Long enough that a pattern of these should be interesting to a developer, but be aware that\n // weak connections, putting clients to sleep, backgrounding etc. could all cause this too.\n this.logger.log(\n `received query results totaling ${prettyMessageMB} which took more than 20s to arrive (${prettyTransitionTime})`,\n );\n }\n\n if (this.debug) {\n // debug means \"reportDebugInfoToConvex\" is set so this can be aggressive.\n this.sendMessage({\n type: \"Event\",\n eventType: \"ClientReceivedTransition\",\n event: { transitionTransitTime, messageLength },\n });\n }\n }\n}\n", "export function newSessionId() {\n return uuidv4();\n}\n\n// From https://stackoverflow.com/a/2117523\nfunction uuidv4() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0,\n v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n", "export interface JwtDecodeOptions {\n header?: boolean;\n}\n\nexport interface JwtHeader {\n typ?: string;\n alg?: string;\n kid?: string;\n}\n\nexport interface JwtPayload {\n iss?: string;\n sub?: string;\n aud?: string[] | string;\n exp?: number;\n nbf?: number;\n iat?: number;\n jti?: string;\n}\n\nexport class InvalidTokenError extends Error {}\n\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\n\nfunction b64DecodeUnicode(str: string) {\n return decodeURIComponent(\n atob(str).replace(/(.)/g, (_m, p) => {\n let code = (p as string).charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n }),\n );\n}\n\nfunction base64UrlDecode(str: string) {\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw new Error(\"base64 string is not of the correct length\");\n }\n\n try {\n return b64DecodeUnicode(output);\n } catch {\n return atob(output);\n }\n}\n\nexport function jwtDecode<T = JwtHeader>(\n token: string,\n options: JwtDecodeOptions & { header: true },\n): T;\nexport function jwtDecode<T = JwtPayload>(\n token: string,\n options?: JwtDecodeOptions,\n): T;\nexport function jwtDecode<T = JwtHeader | JwtPayload>(\n token: string,\n options?: JwtDecodeOptions,\n): T {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\n }\n\n options ||= {};\n\n const pos = options.header === true ? 0 : 1;\n const part = token.split(\".\")[pos];\n\n if (typeof part !== \"string\") {\n throw new InvalidTokenError(\n `Invalid token specified: missing part #${pos + 1}`,\n );\n }\n\n let decoded: string;\n try {\n decoded = base64UrlDecode(part);\n } catch (e) {\n throw new InvalidTokenError(\n `Invalid token specified: invalid base64 for part #${pos + 1} (${(e as Error).message})`,\n );\n }\n\n try {\n return JSON.parse(decoded) as T;\n } catch (e) {\n throw new InvalidTokenError(\n `Invalid token specified: invalid json for part #${pos + 1} (${(e as Error).message})`,\n );\n }\n}\n", "import { Logger } from \"../logging.js\";\nimport { LocalSyncState } from \"./local_state.js\";\nimport { AuthError, IdentityVersion, Transition } from \"./protocol.js\";\nimport { jwtDecode } from \"../../vendor/jwt-decode/index.js\";\n\n// setTimout uses 32 bit integer, so it can only\n// schedule about 24 days in the future.\nconst MAXIMUM_REFRESH_DELAY = 20 * 24 * 60 * 60 * 1000; // 20 days\n\nconst MAX_TOKEN_CONFIRMATION_ATTEMPTS = 2;\n\n/**\n * An async function returning a JWT. Depending on the auth providers\n * configured in convex/auth.config.ts, this may be a JWT-encoded OpenID\n * Connect Identity Token or a traditional JWT.\n *\n * `forceRefreshToken` is `true` if the server rejected a previously\n * returned token or the token is anticipated to expiring soon\n * based on its `exp` time.\n *\n * See {@link ConvexReactClient.setAuth}.\n *\n * @public\n */\nexport type AuthTokenFetcher = (args: {\n forceRefreshToken: boolean;\n}) => Promise<string | null | undefined>;\n\n/**\n * What is provided to the client.\n */\ntype AuthConfig = {\n fetchToken: AuthTokenFetcher;\n onAuthChange: (isAuthenticated: boolean) => void;\n};\n\n/**\n * In general we take 3 steps:\n * 1. Fetch a possibly cached token\n * 2. Immediately fetch a fresh token without using a cache\n * 3. Repeat step 2 before the end of the fresh token's lifetime\n *\n * When we fetch without using a cache we know when the token\n * will expire, and can schedule refetching it.\n *\n * If we get an error before a scheduled refetch, we go back\n * to step 2.\n */\ntype AuthState =\n | { state: \"noAuth\" }\n | {\n state: \"waitingForServerConfirmationOfCachedToken\";\n config: AuthConfig;\n hasRetried: boolean;\n }\n | {\n state: \"initialRefetch\";\n config: AuthConfig;\n }\n | {\n state: \"waitingForServerConfirmationOfFreshToken\";\n config: AuthConfig;\n hadAuth: boolean;\n token: string;\n }\n | {\n state: \"waitingForScheduledRefetch\";\n config: AuthConfig;\n refetchTokenTimeoutId: ReturnType<typeof setTimeout>;\n }\n // Special/weird state when we got a valid token\n // but could not fetch a new one.\n | {\n state: \"notRefetching\";\n config: AuthConfig;\n };\n\n/**\n * Handles the state transitions for auth. The server is the source\n * of truth.\n */\nexport class AuthenticationManager {\n private authState: AuthState = { state: \"noAuth\" };\n // Used to detect races involving `setConfig` calls\n // while a token is being fetched.\n private configVersion = 0;\n // Shared by the BaseClient so that the auth manager can easily inspect it\n private readonly syncState: LocalSyncState;\n // Passed down by BaseClient, sends a message to the server\n private readonly authenticate: (token: string) => IdentityVersion;\n private readonly stopSocket: () => Promise<void>;\n private readonly tryRestartSocket: () => void;\n private readonly pauseSocket: () => void;\n private readonly resumeSocket: () => void;\n // Passed down by BaseClient, sends a message to the server\n private readonly clearAuth: () => void;\n private readonly logger: Logger;\n private readonly refreshTokenLeewaySeconds: number;\n // Number of times we have attempted to confirm the latest token. We retry up\n // to `MAX_TOKEN_CONFIRMATION_ATTEMPTS` times.\n private tokenConfirmationAttempts = 0;\n constructor(\n syncState: LocalSyncState,\n callbacks: {\n authenticate: (token: string) => IdentityVersion;\n stopSocket: () => Promise<void>;\n tryRestartSocket: () => void;\n pauseSocket: () => void;\n resumeSocket: () => void;\n clearAuth: () => void;\n },\n config: {\n refreshTokenLeewaySeconds: number;\n logger: Logger;\n },\n ) {\n this.syncState = syncState;\n this.authenticate = callbacks.authenticate;\n this.stopSocket = callbacks.stopSocket;\n this.tryRestartSocket = callbacks.tryRestartSocket;\n this.pauseSocket = callbacks.pauseSocket;\n this.resumeSocket = callbacks.resumeSocket;\n this.clearAuth = callbacks.clearAuth;\n this.logger = config.logger;\n this.refreshTokenLeewaySeconds = config.refreshTokenLeewaySeconds;\n }\n\n async setConfig(\n fetchToken: AuthTokenFetcher,\n onChange: (isAuthenticated: boolean) => void,\n ) {\n this.resetAuthState();\n this._logVerbose(\"pausing WS for auth token fetch\");\n this.pauseSocket();\n const token = await this.fetchTokenAndGuardAgainstRace(fetchToken, {\n forceRefreshToken: false,\n });\n if (token.isFromOutdatedConfig) {\n return;\n }\n if (token.value) {\n this.setAuthState({\n state: \"waitingForServerConfirmationOfCachedToken\",\n config: { fetchToken, onAuthChange: onChange },\n hasRetried: false,\n });\n this.authenticate(token.value);\n } else {\n this.setAuthState({\n state: \"initialRefetch\",\n config: { fetchToken, onAuthChange: onChange },\n });\n // Try again with `forceRefreshToken: true`\n await this.refetchToken();\n }\n this._logVerbose(\"resuming WS after auth token fetch\");\n this.resumeSocket();\n }\n\n onTransition(serverMessage: Transition) {\n if (\n !this.syncState.isCurrentOrNewerAuthVersion(\n serverMessage.endVersion.identity,\n )\n ) {\n // This is a stale transition - client has moved on to\n // a newer auth version.\n return;\n }\n if (\n serverMessage.endVersion.identity <= serverMessage.startVersion.identity\n ) {\n // This transition did not change auth - it is not a response to Authenticate.\n return;\n }\n\n if (this.authState.state === \"waitingForServerConfirmationOfCachedToken\") {\n this._logVerbose(\"server confirmed auth token is valid\");\n void this.refetchToken();\n this.authState.config.onAuthChange(true);\n return;\n }\n if (this.authState.state === \"waitingForServerConfirmationOfFreshToken\") {\n this._logVerbose(\"server confirmed new auth token is valid\");\n this.scheduleTokenRefetch(this.authState.token);\n this.tokenConfirmationAttempts = 0;\n if (!this.authState.hadAuth) {\n this.authState.config.onAuthChange(true);\n }\n }\n }\n\n onAuthError(serverMessage: AuthError) {\n // If the AuthError is not due to updating the token, and we're currently\n // waiting on the result of a token update, ignore.\n if (\n serverMessage.authUpdateAttempted === false &&\n (this.authState.state === \"waitingForServerConfirmationOfFreshToken\" ||\n this.authState.state === \"waitingForServerConfirmationOfCachedToken\")\n ) {\n this._logVerbose(\"ignoring non-auth token expired error\");\n return;\n }\n const { baseVersion } = serverMessage;\n // Versioned AuthErrors are ignored if the client advanced to\n // a newer auth identity\n // Error are reporting the previous version, since the server\n // didn't advance, hence `+ 1`.\n if (!this.syncState.isCurrentOrNewerAuthVersion(baseVersion + 1)) {\n this._logVerbose(\"ignoring auth error for previous auth attempt\");\n return;\n }\n void this.tryToReauthenticate(serverMessage);\n return;\n }\n\n // This is similar to `refetchToken` defined below, in fact we\n // don't represent them as different states, but it is different\n // in that we pause the WebSocket so that mutations\n // don't retry with bad auth.\n private async tryToReauthenticate(serverMessage: AuthError) {\n this._logVerbose(`attempting to reauthenticate: ${serverMessage.error}`);\n if (\n // No way to fetch another token, kaboom\n this.authState.state === \"noAuth\" ||\n // We failed on a fresh token. After a small number of retries, we give up\n // and clear the auth state to avoid infinite retries.\n (this.authState.state === \"waitingForServerConfirmationOfFreshToken\" &&\n this.tokenConfirmationAttempts >= MAX_TOKEN_CONFIRMATION_ATTEMPTS)\n ) {\n this.logger.error(\n `Failed to authenticate: \"${serverMessage.error}\", check your server auth config`,\n );\n if (this.syncState.hasAuth()) {\n this.syncState.clearAuth();\n }\n if (this.authState.state !== \"noAuth\") {\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n return;\n }\n if (this.authState.state === \"waitingForServerConfirmationOfFreshToken\") {\n this.tokenConfirmationAttempts++;\n this._logVerbose(\n `retrying reauthentication, ${MAX_TOKEN_CONFIRMATION_ATTEMPTS - this.tokenConfirmationAttempts} attempts remaining`,\n );\n }\n\n await this.stopSocket();\n const token = await this.fetchTokenAndGuardAgainstRace(\n this.authState.config.fetchToken,\n {\n forceRefreshToken: true,\n },\n );\n if (token.isFromOutdatedConfig) {\n return;\n }\n\n if (token.value && this.syncState.isNewAuth(token.value)) {\n this.authenticate(token.value);\n this.setAuthState({\n state: \"waitingForServerConfirmationOfFreshToken\",\n config: this.authState.config,\n token: token.value,\n hadAuth:\n this.authState.state === \"notRefetching\" ||\n this.authState.state === \"waitingForScheduledRefetch\",\n });\n } else {\n this._logVerbose(\"reauthentication failed, could not fetch a new token\");\n if (this.syncState.hasAuth()) {\n this.syncState.clearAuth();\n }\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n this.tryRestartSocket();\n }\n\n // Force refetch the token and schedule another refetch\n // before the token expires - an active client should never\n // need to reauthenticate.\n private async refetchToken() {\n if (this.authState.state === \"noAuth\") {\n return;\n }\n this._logVerbose(\"refetching auth token\");\n const token = await this.fetchTokenAndGuardAgainstRace(\n this.authState.config.fetchToken,\n {\n forceRefreshToken: true,\n },\n );\n if (token.isFromOutdatedConfig) {\n return;\n }\n\n if (token.value) {\n if (this.syncState.isNewAuth(token.value)) {\n this.setAuthState({\n state: \"waitingForServerConfirmationOfFreshToken\",\n hadAuth: this.syncState.hasAuth(),\n token: token.value,\n config: this.authState.config,\n });\n this.authenticate(token.value);\n } else {\n this.setAuthState({\n state: \"notRefetching\",\n config: this.authState.config,\n });\n }\n } else {\n this._logVerbose(\"refetching token failed\");\n if (this.syncState.hasAuth()) {\n this.clearAuth();\n }\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n // Restart in case this refetch was triggered via schedule during\n // a reauthentication attempt.\n this._logVerbose(\n \"restarting WS after auth token fetch (if currently stopped)\",\n );\n this.tryRestartSocket();\n }\n\n private scheduleTokenRefetch(token: string) {\n if (this.authState.state === \"noAuth\") {\n return;\n }\n const decodedToken = this.decodeToken(token);\n if (!decodedToken) {\n // This is no longer really possible, because\n // we wait on server response before scheduling token refetch,\n // and the server currently requires JWT tokens.\n this.logger.error(\n \"Auth token is not a valid JWT, cannot refetch the token\",\n );\n return;\n }\n // iat: issued at time, UTC seconds timestamp at which the JWT was issued\n // exp: expiration time, UTC seconds timestamp at which the JWT will expire\n const { iat, exp } = decodedToken as { iat?: number; exp?: number };\n if (!iat || !exp) {\n this.logger.error(\n \"Auth token does not have required fields, cannot refetch the token\",\n );\n return;\n }\n // Because the client and server clocks may be out of sync,\n // we only know that the token will expire after `exp - iat`,\n // and since we just fetched a fresh one we know when that\n // will happen.\n const tokenValiditySeconds = exp - iat;\n if (tokenValiditySeconds <= 2) {\n this.logger.error(\n \"Auth token does not live long enough, cannot refetch the token\",\n );\n return;\n }\n // Attempt to refresh the token `refreshTokenLeewaySeconds` before it expires,\n // or immediately if the token is already expiring soon.\n let delay = Math.min(\n MAXIMUM_REFRESH_DELAY,\n (tokenValiditySeconds - this.refreshTokenLeewaySeconds) * 1000,\n );\n if (delay <= 0) {\n // Refetch immediately, but this might be due to configuring a `refreshTokenLeewaySeconds`\n // that is too large compared to the token's actual lifetime.\n this.logger.warn(\n `Refetching auth token immediately, configured leeway ${this.refreshTokenLeewaySeconds}s is larger than the token's lifetime ${tokenValiditySeconds}s`,\n );\n delay = 0;\n }\n const refetchTokenTimeoutId = setTimeout(() => {\n this._logVerbose(\"running scheduled token refetch\");\n void this.refetchToken();\n }, delay);\n this.setAuthState({\n state: \"waitingForScheduledRefetch\",\n refetchTokenTimeoutId,\n config: this.authState.config,\n });\n this._logVerbose(\n `scheduled preemptive auth token refetching in ${delay}ms`,\n );\n }\n\n // Protects against simultaneous calls to `setConfig`\n // while we're fetching a token\n private async fetchTokenAndGuardAgainstRace(\n fetchToken: AuthTokenFetcher,\n fetchArgs: {\n forceRefreshToken: boolean;\n },\n ) {\n const originalConfigVersion = ++this.configVersion;\n this._logVerbose(\n `fetching token with config version ${originalConfigVersion}`,\n );\n const token = await fetchToken(fetchArgs);\n if (this.configVersion !== originalConfigVersion) {\n // This is a stale config\n this._logVerbose(\n `stale config version, expected ${originalConfigVersion}, got ${this.configVersion}`,\n );\n return { isFromOutdatedConfig: true };\n }\n return { isFromOutdatedConfig: false, value: token };\n }\n\n stop() {\n this.resetAuthState();\n // Bump this in case we are mid-token-fetch when we get stopped\n this.configVersion++;\n this._logVerbose(`config version bumped to ${this.configVersion}`);\n }\n\n private setAndReportAuthFailed(\n onAuthChange: (authenticated: boolean) => void,\n ) {\n onAuthChange(false);\n this.resetAuthState();\n }\n\n private resetAuthState() {\n this.setAuthState({ state: \"noAuth\" });\n }\n\n private setAuthState(newAuth: AuthState) {\n const authStateForLog =\n newAuth.state === \"waitingForServerConfirmationOfFreshToken\"\n ? {\n hadAuth: newAuth.hadAuth,\n state: newAuth.state,\n token: `...${newAuth.token.slice(-7)}`,\n }\n : { state: newAuth.state };\n this._logVerbose(\n `setting auth state to ${JSON.stringify(authStateForLog)}`,\n );\n switch (newAuth.state) {\n case \"waitingForScheduledRefetch\":\n case \"notRefetching\":\n case \"noAuth\":\n this.tokenConfirmationAttempts = 0;\n break;\n case \"waitingForServerConfirmationOfFreshToken\":\n case \"waitingForServerConfirmationOfCachedToken\":\n case \"initialRefetch\":\n break;\n default: {\n newAuth satisfies never;\n }\n }\n if (this.authState.state === \"waitingForScheduledRefetch\") {\n clearTimeout(this.authState.refetchTokenTimeoutId);\n\n // The waitingForScheduledRefetch state is the most quiesced authed state.\n // Let the syncState know that auth is in a good state, so it can reset failure backoffs\n this.syncState.markAuthCompletion();\n }\n this.authState = newAuth;\n }\n\n private decodeToken(token: string) {\n try {\n return jwtDecode(token);\n } catch (e) {\n this._logVerbose(\n `Error decoding token: ${e instanceof Error ? e.message : \"Unknown error\"}`,\n );\n return null;\n }\n }\n\n private _logVerbose(message: string) {\n this.logger.logVerbose(`${message} [v${this.configVersion}]`);\n }\n}\n", "// Marks share a global namespace with other developer code.\nconst markNames = [\n \"convexClientConstructed\",\n \"convexWebSocketOpen\",\n \"convexFirstMessageReceived\",\n] as const;\nexport type MarkName = (typeof markNames)[number];\n\n// Mark details are not reported to the server.\ntype MarkDetail = {\n sessionId: string;\n};\n\n// `PerformanceMark`s are efficient and show up in browser's performance\n// timeline. They can be cleared with `performance.clearMarks()`.\n// This is a memory leak, but a worthwhile one: automatic\n// cleanup would make in-browser debugging more difficult.\nexport function mark(name: MarkName, sessionId: string) {\n const detail: MarkDetail = { sessionId };\n // `performance` APIs exists in browsers, Node.js, Deno, and more but it\n // is not required by the Convex client.\n if (typeof performance === \"undefined\" || !performance.mark) return;\n performance.mark(name, { detail });\n}\n\n// `PerfomanceMark` has a built-in toJSON() but the return type varies\n// between implementations, e.g. Node.js returns details but Chrome does not.\nfunction performanceMarkToJson(mark: PerformanceMark): MarkJson {\n // Remove \"convex\" prefix\n let name = mark.name.slice(\"convex\".length);\n // lowercase the first letter\n name = name.charAt(0).toLowerCase() + name.slice(1);\n return {\n name,\n startTime: mark.startTime,\n };\n}\n\n// Similar to the return type of `PerformanceMark.toJson()`.\nexport type MarkJson = {\n name: string;\n // `startTime` is in milliseconds since the time origin like `performance.now()`.\n // https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp#the_time_origin\n startTime: number;\n};\n\nexport function getMarksReport(sessionId: string): MarkJson[] {\n if (typeof performance === \"undefined\" || !performance.getEntriesByName) {\n return [];\n }\n const allMarks: PerformanceMark[] = [];\n for (const name of markNames) {\n const marks = (\n performance\n .getEntriesByName(name)\n .filter((entry) => entry.entryType === \"mark\") as PerformanceMark[]\n ).filter((mark) => mark.detail.sessionId === sessionId);\n allMarks.push(...marks);\n }\n return allMarks.map(performanceMarkToJson);\n}\n", "/**\n * BaseConvexClient should not be used directly and does not provide a stable\n * interface. It is a \"Base\" client not because it expects to be inherited from\n * but because other clients are built around it.\n *\n * BaseConvexClient is not Convex Function type-aware: it deals\n * with queries as functions that return Value, not the specific value.\n * Use a higher-level library to get types.\n */\nimport { version } from \"../../index.js\";\nimport { convexToJson, Value } from \"../../values/index.js\";\nimport {\n createHybridErrorStacktrace,\n forwardData,\n instantiateDefaultLogger,\n instantiateNoopLogger,\n logFatalError,\n Logger,\n} from \"../logging.js\";\nimport { LocalSyncState } from \"./local_state.js\";\nimport { RequestManager } from \"./request_manager.js\";\nimport {\n OptimisticLocalStore,\n OptimisticUpdate,\n} from \"./optimistic_updates.js\";\nimport {\n OptimisticQueryResults,\n QueryResultsMap,\n} from \"./optimistic_updates_impl.js\";\nimport {\n ActionRequest,\n MutationRequest,\n QueryId,\n QueryJournal,\n ServerMessage,\n RequestId,\n TS,\n UserIdentityAttributes,\n} from \"./protocol.js\";\nimport { RemoteQuerySet } from \"./remote_query_set.js\";\nimport { QueryToken, serializePathAndArgs } from \"./udf_path_utils.js\";\nimport { ReconnectMetadata, WebSocketManager } from \"./web_socket_manager.js\";\nimport { newSessionId } from \"./session.js\";\nimport { FunctionResult } from \"./function_result.js\";\nimport {\n AuthenticationManager,\n AuthTokenFetcher,\n} from \"./authentication_manager.js\";\nexport { type AuthTokenFetcher } from \"./authentication_manager.js\";\nimport { getMarksReport, mark, MarkName } from \"./metrics.js\";\nimport { parseArgs, validateDeploymentUrl } from \"../../common/index.js\";\nimport { ConvexError } from \"../../values/errors.js\";\nimport { jwtDecode } from \"../../vendor/jwt-decode/index.js\";\n\n/**\n * Options for {@link BaseConvexClient}.\n *\n * @public\n */\nexport interface BaseConvexClientOptions {\n /**\n * Whether to prompt the user if they have unsaved changes pending\n * when navigating away or closing a web page.\n *\n * This is only possible when the `window` object exists, i.e. in a browser.\n *\n * The default value is `true` in browsers.\n */\n unsavedChangesWarning?: boolean;\n /**\n * Specifies an alternate\n * [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)\n * constructor to use for client communication with the Convex cloud.\n * The default behavior is to use `WebSocket` from the global environment.\n */\n webSocketConstructor?: typeof WebSocket;\n /**\n * Adds additional logging for debugging purposes.\n *\n * The default value is `false`.\n */\n verbose?: boolean;\n /**\n * A logger, `true`, or `false`. If not provided or `true`, logs to the console.\n * If `false`, logs are not printed anywhere.\n *\n * You can construct your own logger to customize logging to log elsewhere.\n * A logger is an object with 4 methods: log(), warn(), error(), and logVerbose().\n * These methods can receive multiple arguments of any types, like console.log().\n */\n logger?: Logger | boolean;\n /**\n * Sends additional metrics to Convex for debugging purposes.\n *\n * The default value is `false`.\n */\n reportDebugInfoToConvex?: boolean;\n /**\n * This API is experimental: it may change or disappear.\n *\n * A function to call on receiving abnormal WebSocket close messages from the\n * connected Convex deployment. The content of these messages is not stable,\n * it is an implementation detail that may change.\n *\n * Consider this API an observability stopgap until higher level codes with\n * recommendations on what to do are available, which could be a more stable\n * interface instead of `string`.\n *\n * Check `connectionState` for more quantitative metrics about connection status.\n */\n onServerDisconnectError?: (message: string) => void;\n /**\n * Skip validating that the Convex deployment URL looks like\n * `https://happy-animal-123.convex.cloud` or localhost.\n *\n * This can be useful if running a self-hosted Convex backend that uses a different\n * URL.\n *\n * The default value is `false`\n */\n skipConvexDeploymentUrlCheck?: boolean;\n /**\n * If using auth, the number of seconds before a token expires that we should refresh it.\n *\n * The default value is `10`.\n */\n authRefreshTokenLeewaySeconds?: number;\n /**\n * This API is experimental: it may change or disappear.\n *\n * Whether query, mutation, and action requests should be held back\n * until the first auth token can be sent.\n *\n * Opting into this behavior works well for pages that should\n * only be viewed by authenticated clients.\n *\n * Defaults to false, not waiting for an auth token.\n */\n expectAuth?: boolean;\n}\n\n/**\n * State describing the client's connection with the Convex backend.\n *\n * @public\n */\nexport type ConnectionState = {\n hasInflightRequests: boolean;\n isWebSocketConnected: boolean;\n timeOfOldestInflightRequest: Date | null;\n /**\n * True if the client has ever opened a WebSocket to the \"ready\" state.\n */\n hasEverConnected: boolean;\n /**\n * The number of times this client has connected to the Convex backend.\n *\n * A number of things can cause the client to reconnect -- server errors,\n * bad internet, auth expiring. But this number being high is an indication\n * that the client is having trouble keeping a stable connection.\n */\n connectionCount: number;\n /**\n * The number of times this client has tried (and failed) to connect to the Convex backend.\n */\n connectionRetries: number;\n /**\n * The number of mutations currently in flight.\n */\n inflightMutations: number;\n /**\n * The number of actions currently in flight.\n */\n inflightActions: number;\n};\n\n/**\n * Options for {@link BaseConvexClient.subscribe}.\n *\n * @public\n */\nexport interface SubscribeOptions {\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 | undefined;\n}\n\n/**\n * Options for {@link BaseConvexClient.mutation}.\n *\n * @public\n */\nexport interface MutationOptions {\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<any> | undefined;\n}\n\n/**\n * Type describing updates to a query within a `Transition`.\n *\n * @public\n */\nexport type QueryModification =\n // `undefined` generally comes from an optimistic update setting the query to be loading\n { kind: \"Updated\"; result: FunctionResult | undefined } | { kind: \"Removed\" };\n\n/**\n * Object describing a transition passed into the `onTransition` handler.\n *\n * These can be from receiving a transition from the server, or from applying an\n * optimistic update locally.\n *\n * @public\n */\nexport type Transition = {\n queries: Array<{ token: QueryToken; modification: QueryModification }>;\n reflectedMutations: Array<{ requestId: RequestId; result: FunctionResult }>;\n timestamp: TS;\n};\n\n/**\n * Low-level client for directly integrating state management libraries\n * with Convex.\n *\n * Most developers should use higher level clients, like\n * the {@link ConvexHttpClient} or the React hook based {@link react.ConvexReactClient}.\n *\n * @public\n */\nexport class BaseConvexClient {\n private readonly address: string;\n private readonly state: LocalSyncState;\n private readonly requestManager: RequestManager;\n private readonly webSocketManager: WebSocketManager;\n private readonly authenticationManager: AuthenticationManager;\n private remoteQuerySet: RemoteQuerySet;\n private readonly optimisticQueryResults: OptimisticQueryResults;\n private _transitionHandlerCounter = 0;\n private _nextRequestId: RequestId;\n private _onTransitionFns: Map<number, (transition: Transition) => void> =\n new Map();\n private readonly _sessionId: string;\n private firstMessageReceived = false;\n private readonly debug: boolean;\n private readonly logger: Logger;\n private maxObservedTimestamp: TS | undefined;\n private connectionStateSubscribers = new Map<\n number,\n (connectionState: ConnectionState) => void\n >();\n private nextConnectionStateSubscriberId: number = 0;\n private _lastPublishedConnectionState: ConnectionState | 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 onTransition - A callback receiving an array of query tokens\n * corresponding to query results that have changed -- additional handlers\n * can be added via `addOnTransitionHandler`.\n * @param options - See {@link BaseConvexClientOptions} for a full description.\n */\n constructor(\n address: string,\n onTransition: (updatedQueries: QueryToken[]) => void,\n options?: BaseConvexClientOptions,\n ) {\n if (typeof address === \"object\") {\n throw new Error(\n \"Passing a ClientConfig object is no longer supported. Pass the URL of the Convex deployment as a string directly.\",\n );\n }\n if (options?.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n options = { ...options };\n const authRefreshTokenLeewaySeconds =\n options.authRefreshTokenLeewaySeconds ?? 10;\n let webSocketConstructor = options.webSocketConstructor;\n if (!webSocketConstructor && typeof WebSocket === \"undefined\") {\n throw new Error(\n \"No WebSocket global variable defined! To use Convex in an environment without WebSocket try the HTTP client: https://docs.convex.dev/api/classes/browser.ConvexHttpClient\",\n );\n }\n webSocketConstructor = webSocketConstructor || WebSocket;\n this.debug = options.reportDebugInfoToConvex ?? false;\n this.address = address;\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 // Substitute http(s) with ws(s)\n const i = address.search(\"://\");\n if (i === -1) {\n throw new Error(\"Provided address was not an absolute URL.\");\n }\n const origin = address.substring(i + 3); // move past the double slash\n const protocol = address.substring(0, i);\n let wsProtocol;\n if (protocol === \"http\") {\n wsProtocol = \"ws\";\n } else if (protocol === \"https\") {\n wsProtocol = \"wss\";\n } else {\n throw new Error(`Unknown parent protocol ${protocol}`);\n }\n const wsUri = `${wsProtocol}://${origin}/api/${version}/sync`;\n\n this.state = new LocalSyncState();\n this.remoteQuerySet = new RemoteQuerySet(\n (queryId) => this.state.queryPath(queryId),\n this.logger,\n );\n this.requestManager = new RequestManager(\n this.logger,\n this.markConnectionStateDirty,\n );\n\n // This is a callback for AuthenticationManager (which can't call\n // this synchronously, the callback wouldn't work) so the initial\n // pause for expectAuth we call it at the end of this constructor.\n const pauseSocket = () => {\n this.webSocketManager.pause();\n this.state.pause();\n };\n this.authenticationManager = new AuthenticationManager(\n this.state,\n {\n authenticate: (token) => {\n const message = this.state.setAuth(token);\n this.webSocketManager.sendMessage(message);\n return message.baseVersion;\n },\n stopSocket: () => this.webSocketManager.stop(),\n tryRestartSocket: () => this.webSocketManager.tryRestart(),\n pauseSocket,\n resumeSocket: () => this.webSocketManager.resume(),\n clearAuth: () => {\n this.clearAuth();\n },\n },\n {\n logger: this.logger,\n refreshTokenLeewaySeconds: authRefreshTokenLeewaySeconds,\n },\n );\n this.optimisticQueryResults = new OptimisticQueryResults();\n this.addOnTransitionHandler((transition) => {\n onTransition(transition.queries.map((q) => q.token));\n });\n this._nextRequestId = 0;\n this._sessionId = newSessionId();\n\n const { unsavedChangesWarning } = options;\n if (\n typeof window === \"undefined\" ||\n typeof window.addEventListener === \"undefined\"\n ) {\n if (unsavedChangesWarning === true) {\n throw new Error(\n \"unsavedChangesWarning requested, but window.addEventListener not found! Remove {unsavedChangesWarning: true} from Convex client options.\",\n );\n }\n } else if (unsavedChangesWarning !== false) {\n // Listen for tab close events and notify the user on unsaved changes.\n window.addEventListener(\"beforeunload\", (e) => {\n if (this.requestManager.hasIncompleteRequests()) {\n // There are 3 different ways to trigger this pop up so just try all of\n // them.\n\n e.preventDefault();\n // This confirmation message doesn't actually appear in most modern\n // browsers but we tried.\n const confirmationMessage =\n \"Are you sure you want to leave? Your changes may not be saved.\";\n // Recommended method for legacy (IE) browsers.\n // casts to avoid deprecation notices\n ((e || (window as any).event) as any).returnValue =\n confirmationMessage;\n return confirmationMessage;\n }\n });\n }\n\n this.webSocketManager = new WebSocketManager(\n wsUri,\n {\n onOpen: (reconnectMetadata: ReconnectMetadata) => {\n // We have a new WebSocket!\n this.mark(\"convexWebSocketOpen\");\n this.webSocketManager.sendMessage({\n ...reconnectMetadata,\n type: \"Connect\",\n sessionId: this._sessionId,\n maxObservedTimestamp: this.maxObservedTimestamp,\n });\n\n // Throw out our remote query, reissue queries\n // and outstanding mutations, and reauthenticate.\n this.remoteQuerySet = new RemoteQuerySet(\n (queryId) => this.state.queryPath(queryId),\n this.logger,\n );\n const [querySetModification, authModification] = this.state.restart();\n if (authModification) {\n this.webSocketManager.sendMessage(authModification);\n }\n this.webSocketManager.sendMessage(querySetModification);\n for (const message of this.requestManager.restart()) {\n this.webSocketManager.sendMessage(message);\n }\n },\n onResume: () => {\n const [querySetModification, authModification] = this.state.resume();\n if (authModification) {\n this.webSocketManager.sendMessage(authModification);\n }\n if (querySetModification) {\n this.webSocketManager.sendMessage(querySetModification);\n }\n for (const message of this.requestManager.resume()) {\n this.webSocketManager.sendMessage(message);\n }\n },\n onMessage: (serverMessage: ServerMessage) => {\n // Metrics events grow linearly with reconnection attempts so this\n // conditional prevents n^2 metrics reporting.\n if (!this.firstMessageReceived) {\n this.firstMessageReceived = true;\n this.mark(\"convexFirstMessageReceived\");\n this.reportMarks();\n }\n switch (serverMessage.type) {\n case \"Transition\": {\n this.observedTimestamp(serverMessage.endVersion.ts);\n this.authenticationManager.onTransition(serverMessage);\n this.remoteQuerySet.transition(serverMessage);\n this.state.transition(serverMessage);\n const completedRequests = this.requestManager.removeCompleted(\n this.remoteQuerySet.timestamp(),\n );\n this.notifyOnQueryResultChanges(completedRequests);\n break;\n }\n case \"MutationResponse\": {\n if (serverMessage.success) {\n this.observedTimestamp(serverMessage.ts);\n }\n const completedMutationInfo =\n this.requestManager.onResponse(serverMessage);\n if (completedMutationInfo !== null) {\n this.notifyOnQueryResultChanges(\n new Map([\n [\n completedMutationInfo.requestId,\n completedMutationInfo.result,\n ],\n ]),\n );\n }\n break;\n }\n case \"ActionResponse\": {\n this.requestManager.onResponse(serverMessage);\n break;\n }\n case \"AuthError\": {\n this.authenticationManager.onAuthError(serverMessage);\n break;\n }\n case \"FatalError\": {\n const error = logFatalError(this.logger, serverMessage.error);\n void this.webSocketManager.terminate();\n throw error;\n }\n default: {\n serverMessage satisfies never;\n }\n }\n\n return {\n hasSyncedPastLastReconnect: this.hasSyncedPastLastReconnect(),\n };\n },\n onServerDisconnectError: options.onServerDisconnectError,\n },\n webSocketConstructor,\n this.logger,\n this.markConnectionStateDirty,\n this.debug,\n );\n this.mark(\"convexClientConstructed\");\n\n // Begin client in a paused state waiting for an auth token.\n if (options.expectAuth) {\n pauseSocket();\n }\n }\n\n /**\n * Return true if there is outstanding work from prior to the time of the most recent restart.\n * This indicates that the client has not proven itself to have gotten past the issue that\n * potentially led to the restart. Use this to influence when to reset backoff after a failure.\n */\n private hasSyncedPastLastReconnect() {\n const hasSyncedPastLastReconnect =\n this.requestManager.hasSyncedPastLastReconnect() &&\n this.state.hasSyncedPastLastReconnect();\n return hasSyncedPastLastReconnect;\n }\n\n private observedTimestamp(observedTs: TS) {\n if (\n this.maxObservedTimestamp === undefined ||\n this.maxObservedTimestamp.lessThanOrEqual(observedTs)\n ) {\n this.maxObservedTimestamp = observedTs;\n }\n }\n\n getMaxObservedTimestamp() {\n return this.maxObservedTimestamp;\n }\n\n /**\n * Compute the current query results based on the remoteQuerySet and the\n * current optimistic updates and call `onTransition` for all the changed\n * queries.\n *\n * @param completedMutations - A set of mutation IDs whose optimistic updates\n * are no longer needed.\n */\n private notifyOnQueryResultChanges(\n completedRequests: Map<RequestId, FunctionResult>,\n ) {\n const remoteQueryResults: Map<QueryId, FunctionResult> =\n this.remoteQuerySet.remoteQueryResults();\n const queryTokenToValue: QueryResultsMap = new Map();\n for (const [queryId, result] of remoteQueryResults) {\n const queryToken = this.state.queryToken(queryId);\n // It's possible that we've already unsubscribed to this query but\n // the server hasn't learned about that yet. If so, ignore this one.\n\n if (queryToken !== null) {\n const query = {\n result,\n udfPath: this.state.queryPath(queryId)!,\n args: this.state.queryArgs(queryId)!,\n };\n queryTokenToValue.set(queryToken, query);\n }\n }\n\n // Query tokens that are new (because of new server results or new local optimistic updates)\n // or differ from old values (because of changes from local optimistic updates or new results\n // from the server).\n const changedQueryTokens =\n this.optimisticQueryResults.ingestQueryResultsFromServer(\n queryTokenToValue,\n new Set(completedRequests.keys()),\n );\n\n this.handleTransition({\n queries: changedQueryTokens.map((token) => {\n const optimisticResult =\n this.optimisticQueryResults.rawQueryResult(token);\n return {\n token,\n modification: {\n kind: \"Updated\" as const,\n result: optimisticResult,\n },\n };\n }),\n reflectedMutations: Array.from(completedRequests).map(\n ([requestId, result]) => ({\n requestId,\n result,\n }),\n ),\n timestamp: this.remoteQuerySet.timestamp(),\n });\n }\n\n private handleTransition(transition: Transition) {\n for (const fn of this._onTransitionFns.values()) {\n fn(transition);\n }\n }\n\n /**\n * Add a handler that will be called on a transition.\n *\n * Any external side effects (e.g. setting React state) should be handled here.\n *\n * @param fn\n *\n * @returns\n */\n addOnTransitionHandler(fn: (transition: Transition) => void) {\n const id = this._transitionHandlerCounter++;\n this._onTransitionFns.set(id, fn);\n return () => this._onTransitionFns.delete(id);\n }\n\n /**\n * Get the current JWT auth token and decoded claims.\n */\n getCurrentAuthClaims():\n | { token: string; decoded: Record<string, any> }\n | undefined {\n const authToken = this.state.getAuth();\n let decoded: Record<string, any> = {};\n if (authToken && authToken.tokenType === \"User\") {\n try {\n decoded = authToken ? jwtDecode(authToken.value) : {};\n } catch {\n decoded = {};\n }\n } else {\n return undefined;\n }\n return { token: authToken.value, decoded };\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 */\n setAuth(\n fetchToken: AuthTokenFetcher,\n onChange: (isAuthenticated: boolean) => void,\n ) {\n void this.authenticationManager.setConfig(fetchToken, onChange);\n }\n\n hasAuth() {\n return this.state.hasAuth();\n }\n\n /** @internal */\n setAdminAuth(value: string, fakeUserIdentity?: UserIdentityAttributes) {\n const message = this.state.setAdminAuth(value, fakeUserIdentity);\n this.webSocketManager.sendMessage(message);\n }\n\n clearAuth() {\n const message = this.state.clearAuth();\n this.webSocketManager.sendMessage(message);\n }\n\n /**\n * Subscribe to a query function.\n *\n * Whenever this query's result changes, the `onTransition` callback\n * passed into the constructor will be called.\n *\n * @param name - The name of the query.\n * @param args - An arguments object for the query. If this is omitted, the\n * arguments will be `{}`.\n * @param options - A {@link SubscribeOptions} options object for this query.\n\n * @returns An object containing a {@link QueryToken} corresponding to this\n * query and an `unsubscribe` callback.\n */\n subscribe(\n name: string,\n args?: Record<string, Value>,\n options?: SubscribeOptions,\n ): { queryToken: QueryToken; unsubscribe: () => void } {\n const argsObject = parseArgs(args);\n\n const { modification, queryToken, unsubscribe } = this.state.subscribe(\n name,\n argsObject,\n options?.journal,\n options?.componentPath,\n );\n if (modification !== null) {\n this.webSocketManager.sendMessage(modification);\n }\n return {\n queryToken,\n unsubscribe: () => {\n const modification = unsubscribe();\n if (modification) {\n this.webSocketManager.sendMessage(modification);\n }\n },\n };\n }\n\n /**\n * A query result based only on the current, local state.\n *\n * The only way this will return a value is if we're already subscribed to the\n * query or its value has been set optimistically.\n */\n localQueryResult(\n udfPath: string,\n args?: Record<string, Value>,\n ): Value | undefined {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(udfPath, argsObject);\n return this.optimisticQueryResults.queryResult(queryToken);\n }\n\n /**\n * Get query result by query token based on current, local state\n *\n * The only way this will return a value is if we're already subscribed to the\n * query or its value has been set optimistically.\n *\n * @internal\n */\n localQueryResultByToken(queryToken: QueryToken): Value | undefined {\n return this.optimisticQueryResults.queryResult(queryToken);\n }\n\n /**\n * Whether local query result is available for a token.\n *\n * This method does not throw if the result is an error.\n *\n * @internal\n */\n hasLocalQueryResultByToken(queryToken: QueryToken): boolean {\n return this.optimisticQueryResults.hasQueryResult(queryToken);\n }\n\n /**\n * @internal\n */\n localQueryLogs(\n udfPath: string,\n args?: Record<string, Value>,\n ): string[] | undefined {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(udfPath, argsObject);\n return this.optimisticQueryResults.queryLogs(queryToken);\n }\n\n /**\n * Retrieve the current {@link QueryJournal} for this query function.\n *\n * If we have not yet received a result for this query, this will be `undefined`.\n *\n * @param name - The name of the query.\n * @param args - The arguments object for this query.\n * @returns The query's {@link QueryJournal} or `undefined`.\n */\n queryJournal(\n name: string,\n args?: Record<string, Value>,\n ): QueryJournal | undefined {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(name, argsObject);\n return this.state.queryJournal(queryToken);\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 const wsConnectionState = this.webSocketManager.connectionState();\n return {\n hasInflightRequests: this.requestManager.hasInflightRequests(),\n isWebSocketConnected: wsConnectionState.isConnected,\n hasEverConnected: wsConnectionState.hasEverConnected,\n connectionCount: wsConnectionState.connectionCount,\n connectionRetries: wsConnectionState.connectionRetries,\n timeOfOldestInflightRequest:\n this.requestManager.timeOfOldestInflightRequest(),\n inflightMutations: this.requestManager.inflightMutations(),\n inflightActions: this.requestManager.inflightActions(),\n };\n }\n\n /**\n * Call this whenever the connection state may have changed in a way that could\n * require publishing it. Schedules a possibly update.\n */\n private markConnectionStateDirty = () => {\n void Promise.resolve().then(() => {\n const curConnectionState = this.connectionState();\n if (\n JSON.stringify(curConnectionState) !==\n JSON.stringify(this._lastPublishedConnectionState)\n ) {\n this._lastPublishedConnectionState = curConnectionState;\n for (const cb of this.connectionStateSubscribers.values()) {\n // One of these callback throwing will prevent other callbacks\n // from running but will not leave the client in a undefined state.\n cb(curConnectionState);\n }\n }\n });\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 *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(\n cb: (connectionState: ConnectionState) => void,\n ): () => void {\n const id = this.nextConnectionStateSubscriberId++;\n this.connectionStateSubscribers.set(id, cb);\n return () => {\n this.connectionStateSubscribers.delete(id);\n };\n }\n\n /**\n * Execute a mutation function.\n *\n * @param name - The name of the mutation.\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 this mutation.\n\n * @returns - A promise of the mutation's result.\n */\n async mutation(\n name: string,\n args?: Record<string, Value>,\n options?: MutationOptions,\n ): Promise<any> {\n const result = await this.mutationInternal(name, args, options);\n if (!result.success) {\n if (result.errorData !== undefined) {\n throw forwardData(\n result,\n new ConvexError(\n createHybridErrorStacktrace(\"mutation\", name, result),\n ),\n );\n }\n throw new Error(createHybridErrorStacktrace(\"mutation\", name, result));\n }\n return result.value;\n }\n\n /**\n * @internal\n */\n async mutationInternal(\n udfPath: string,\n args?: Record<string, Value>,\n options?: MutationOptions,\n componentPath?: string,\n ): Promise<FunctionResult> {\n const { mutationPromise } = this.enqueueMutation(\n udfPath,\n args,\n options,\n componentPath,\n );\n return mutationPromise;\n }\n\n /**\n * @internal\n */\n enqueueMutation(\n udfPath: string,\n args?: Record<string, Value>,\n options?: MutationOptions,\n componentPath?: string,\n ): { requestId: RequestId; mutationPromise: Promise<FunctionResult> } {\n const mutationArgs = parseArgs(args);\n this.tryReportLongDisconnect();\n const requestId = this.nextRequestId;\n this._nextRequestId++;\n\n if (options !== undefined) {\n const optimisticUpdate = options.optimisticUpdate;\n if (optimisticUpdate !== undefined) {\n const wrappedUpdate = (localQueryStore: OptimisticLocalStore) => {\n const result: unknown = optimisticUpdate(\n localQueryStore,\n mutationArgs,\n );\n if (result instanceof Promise) {\n this.logger.warn(\n \"Optimistic update handler returned a Promise. Optimistic updates should be synchronous.\",\n );\n }\n };\n\n const changedQueryTokens =\n this.optimisticQueryResults.applyOptimisticUpdate(\n wrappedUpdate,\n requestId,\n );\n\n const changedQueries = changedQueryTokens.map((token) => {\n const localResult = this.localQueryResultByToken(token);\n return {\n token,\n modification: {\n kind: \"Updated\" as const,\n result:\n localResult === undefined\n ? undefined\n : {\n success: true as const,\n value: localResult,\n logLines: [],\n },\n },\n };\n });\n this.handleTransition({\n queries: changedQueries,\n reflectedMutations: [],\n timestamp: this.remoteQuerySet.timestamp(),\n });\n }\n }\n\n const message: MutationRequest = {\n type: \"Mutation\",\n requestId,\n udfPath,\n componentPath,\n args: [convexToJson(mutationArgs)],\n };\n const mightBeSent = this.webSocketManager.sendMessage(message);\n const mutationPromise = this.requestManager.request(message, mightBeSent);\n return {\n requestId,\n mutationPromise,\n };\n }\n\n /**\n * Execute an action function.\n *\n * @param name - The name of the action.\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 async action(name: string, args?: Record<string, Value>): Promise<any> {\n const result = await this.actionInternal(name, args);\n if (!result.success) {\n if (result.errorData !== undefined) {\n throw forwardData(\n result,\n new ConvexError(createHybridErrorStacktrace(\"action\", name, result)),\n );\n }\n throw new Error(createHybridErrorStacktrace(\"action\", name, result));\n }\n return result.value;\n }\n\n /**\n * @internal\n */\n async actionInternal(\n udfPath: string,\n args?: Record<string, Value>,\n componentPath?: string,\n ): Promise<FunctionResult> {\n const actionArgs = parseArgs(args);\n const requestId = this.nextRequestId;\n this._nextRequestId++;\n this.tryReportLongDisconnect();\n\n const message: ActionRequest = {\n type: \"Action\",\n requestId,\n udfPath,\n componentPath,\n args: [convexToJson(actionArgs)],\n };\n\n const mightBeSent = this.webSocketManager.sendMessage(message);\n return this.requestManager.request(message, mightBeSent);\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 an {@link BaseConvexClient} 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.authenticationManager.stop();\n return this.webSocketManager.terminate();\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 * @internal\n */\n get nextRequestId() {\n return this._nextRequestId;\n }\n\n /**\n * @internal\n */\n get sessionId() {\n return this._sessionId;\n }\n\n // Instance property so that `mark()` doesn't need to be called as a method.\n private mark = (name: MarkName) => {\n if (this.debug) {\n mark(name, this.sessionId);\n }\n };\n\n /**\n * Reports performance marks to the server. This should only be called when\n * we have a functional websocket.\n */\n private reportMarks() {\n if (this.debug) {\n const report = getMarksReport(this.sessionId);\n this.webSocketManager.sendMessage({\n type: \"Event\",\n eventType: \"ClientConnect\",\n event: report,\n });\n }\n }\n\n private tryReportLongDisconnect() {\n if (!this.debug) {\n return;\n }\n const timeOfOldestRequest =\n this.connectionState().timeOfOldestInflightRequest;\n if (\n timeOfOldestRequest === null ||\n Date.now() - timeOfOldestRequest.getTime() <= 60 * 1000\n ) {\n return;\n }\n const endpoint = `${this.address}/api/debug_event`;\n fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n },\n body: JSON.stringify({ event: \"LongWebsocketDisconnect\" }),\n })\n .then((response) => {\n if (!response.ok) {\n this.logger.warn(\n \"Analytics request failed with response:\",\n response.body,\n );\n }\n })\n .catch((error) => {\n this.logger.warn(\"Analytics response failed with error:\", error);\n });\n }\n}\n", "import type { PaginationResult } from \"../../server/index.js\";\nimport type { Infer, Value } from \"../../values/index.js\";\nimport type { paginationOptsValidator } from \"../../server/index.js\";\n\nexport type PaginationStatus =\n | \"LoadingFirstPage\"\n | \"CanLoadMore\"\n | \"LoadingMore\"\n | \"Exhausted\";\n\nexport type PaginatedQueryResult<T> = {\n results: T[];\n status: PaginationStatus;\n loadMore: LoadMoreOfPaginatedQuery;\n};\n\n/**\n * Returns whether loading more was actually initiated; in cases where\n * a paginated query is already loading more items or there are no more\n * items available, calling loadMore() may do nothing.\n */\nexport type LoadMoreOfPaginatedQuery = (numItems: number) => boolean;\n\n// The arguments for each page query.\nexport function asPaginationArgs(value: Value): Record<string, Value> & {\n paginationOpts: Infer<typeof paginationOptsValidator>;\n} {\n if (typeof (value as any).paginationOpts.numItems !== \"number\") {\n throw new Error(`Not valid paginated query args: ${JSON.stringify(value)}`);\n }\n return value as unknown as Record<string, Value> & {\n paginationOpts: Infer<typeof paginationOptsValidator>;\n };\n}\n\n/**\n * Validates that a Value is a valid pagination result and returns it cast to PaginationResult.\n */\nexport function asPaginationResult(value: Value): PaginationResult<Value> {\n if (\n typeof value !== \"object\" ||\n value === null ||\n !Array.isArray((value as any).page) ||\n typeof (value as any).isDone !== \"boolean\" ||\n typeof (value as any).continueCursor !== \"string\"\n ) {\n throw new Error(`Not a valid paginated query result: ${value?.toString()}`);\n }\n return value as unknown as PaginationResult<Value>;\n}\n", "/**\n * PaginatedQueryClient maps subscriptions to paginated queries to the\n * individual page queries and handles page splits.\n *\n * In order to process all modified queries, paginated and normal, in the same\n * synchronous call the PaginatedQueryClient transition should be used exclusively.\n *\n * Like the BaseConvexClient, this client is not Convex Function type-aware: it deals\n * with queries as functions that return Value, not the specific value.\n * Use a higher-level library to get types.\n */\n\nimport { Value } from \"../../values/index.js\";\nimport {\n PaginatedQueryToken,\n QueryToken,\n serializePaginatedPathAndArgs,\n canonicalizeUdfPath,\n} from \"./udf_path_utils.js\";\nimport { BaseConvexClient, Transition } from \"./client.js\";\nimport {\n PaginatedQueryResult,\n PaginationStatus,\n asPaginationResult,\n} from \"./pagination.js\";\nimport { TS } from \"./protocol.js\";\nimport { Long } from \"../../vendor/long.js\";\n\ntype QueryPageKey = number;\n\n/**\n * Represents a paginated query subscription with multiple pages.\n *\n * To know the order of pages it's necessary to consult `pageKeys`.\n * The pages in this array are active, they constitute a gapless sequence of results.\n * Some pages are not in this array: they may be waiting for data for a page split.\n */\ntype LocalPaginatedQuery = {\n token: PaginatedQueryToken;\n canonicalizedUdfPath: string;\n args: Record<string, Value>; // WITHOUT paginationOpts\n numSubscribers: number;\n options: { initialNumItems: number };\n nextPageKey: QueryPageKey;\n pageKeys: QueryPageKey[]; // These pages make up the active page queries.\n // Map page keys to their query subscriptions\n pageKeyToQuery: Map<\n QueryPageKey,\n { queryToken: QueryToken; unsubscribe: () => void }\n >;\n ongoingSplits: Map<QueryPageKey, [QueryPageKey, QueryPageKey]>;\n skip: boolean;\n\n // Give separate uses of the query separate identities,\n // which may be removed in the future to improve caching.\n id: number;\n};\n\nexport interface SubscribeToPaginatedQueryOptions {\n initialNumItems: number;\n id: number;\n}\n\ntype AnyPaginatedQueryResult = PaginatedQueryResult<Value>;\n\nexport type PaginatedQueryModification =\n | { kind: \"Updated\"; result: AnyPaginatedQueryResult | undefined }\n | { kind: \"Removed\" };\n\nexport type ExtendedTransition = Transition & {\n paginatedQueries: Array<{\n token: PaginatedQueryToken;\n modification: PaginatedQueryModification;\n }>;\n};\n\nexport class PaginatedQueryClient {\n private paginatedQuerySet: Map<PaginatedQueryToken, LocalPaginatedQuery> =\n new Map();\n // hold onto a real Transition so we can construct synthetic ones with that timestamp\n private lastTransitionTs: TS;\n\n constructor(\n private client: BaseConvexClient,\n private onTransition: (transition: ExtendedTransition) => void,\n ) {\n // Nonsense initial value to construct synthetic Transitions\n this.lastTransitionTs = Long.fromNumber(0);\n this.client.addOnTransitionHandler((transition: Transition) =>\n this.onBaseTransition(transition),\n );\n }\n\n /**\n * Subscribe to a paginated query.\n *\n * @param name - The name of the paginated query function\n * @param args - Arguments for the query (excluding paginationOpts)\n * @param options - Pagination options including initialNumItems\n * @returns Object with paginatedQueryToken and unsubscribe function\n */\n subscribe(\n name: string,\n args: Record<string, Value>,\n options: SubscribeToPaginatedQueryOptions,\n ): {\n paginatedQueryToken: PaginatedQueryToken;\n unsubscribe: () => void;\n } {\n const canonicalizedUdfPath = canonicalizeUdfPath(name);\n // Note that only the expected options are included in the serialization.\n const token = serializePaginatedPathAndArgs(\n canonicalizedUdfPath,\n args,\n options,\n );\n\n const unsubscribe = () => this.removePaginatedQuerySubscriber(token);\n\n const existingEntry = this.paginatedQuerySet.get(token);\n if (existingEntry) {\n existingEntry.numSubscribers += 1;\n return {\n paginatedQueryToken: token,\n unsubscribe,\n };\n }\n\n // Create new paginated query\n this.paginatedQuerySet.set(token, {\n token,\n canonicalizedUdfPath,\n args,\n numSubscribers: 1,\n options: { initialNumItems: options.initialNumItems },\n nextPageKey: 0,\n pageKeys: [],\n pageKeyToQuery: new Map(),\n ongoingSplits: new Map(),\n skip: false,\n id: options.id,\n });\n\n this.addPageToPaginatedQuery(token, null, options.initialNumItems);\n\n return {\n paginatedQueryToken: token,\n unsubscribe,\n };\n }\n\n /**\n * Get current results for a paginated query based on local state.\n *\n * Throws an error when one of the pages has errored.\n */\n localQueryResult(\n name: string,\n args: Record<string, Value>,\n options: { initialNumItems: number; id: number },\n ): AnyPaginatedQueryResult | undefined {\n const canonicalizedUdfPath = canonicalizeUdfPath(name);\n const token = serializePaginatedPathAndArgs(\n canonicalizedUdfPath,\n args,\n options,\n );\n return this.localQueryResultByToken(token);\n }\n\n /**\n * @internal\n */\n localQueryResultByToken(\n token: PaginatedQueryToken,\n ): AnyPaginatedQueryResult | undefined {\n // undefined is probably the wrong value! Should be a real paginated query result for loading!\n // Butit's confusing why we'd ever get this, I guess some flows call localQueryResult before\n // subscribing? That's proabbly fair but is it consistent with the normal client?\n // What is the invariant here, will a token always exist? Or can a lookup occur at any time?\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n return undefined;\n }\n\n const activePages = this.activePageQueryTokens(paginatedQuery);\n if (activePages.length === 0) {\n return {\n results: [],\n status: \"LoadingFirstPage\",\n loadMore: (numItems: number) => {\n return this.loadMoreOfPaginatedQuery(token, numItems);\n },\n };\n }\n\n let allResults: Value[] = [];\n\n // Some page is loading (this isn't supposed to happen to any page but the last)\n let hasUndefined = false;\n let isDone = false;\n\n for (const pageToken of activePages) {\n // This throws, don't catch it, it should bubble up.\n // It might be a InvalidCursor Error. If it is, this query\n // should be reset (for now, use a new ID to ensure new state).\n //\n // In the future this might be caught and dealt with here but\n // an ID-based solution won't work here, ID is an intrinsic property\n // of this paginated query.\n const result = this.client.localQueryResultByToken(pageToken);\n\n if (result === undefined) {\n hasUndefined = true;\n isDone = false;\n continue;\n }\n\n const paginationResult = asPaginationResult(result);\n allResults = allResults.concat(paginationResult.page);\n // logic only relevant to the last page, we just happen to run it each time\n isDone = !!paginationResult.isDone;\n }\n\n let status: PaginationStatus;\n if (hasUndefined) {\n status = allResults.length === 0 ? \"LoadingFirstPage\" : \"LoadingMore\";\n } else if (isDone) {\n status = \"Exhausted\";\n } else {\n status = \"CanLoadMore\";\n }\n\n return {\n results: allResults,\n status,\n loadMore: (numItems: number) => {\n return this.loadMoreOfPaginatedQuery(token, numItems);\n },\n };\n }\n\n private onBaseTransition(transition: Transition) {\n const changedBaseTokens = transition.queries.map((q) => q.token);\n const changed = this.queriesContainingTokens(changedBaseTokens);\n\n let paginatedQueries: Array<{\n token: PaginatedQueryToken;\n modification: PaginatedQueryModification;\n }> = [];\n\n if (changed.length > 0) {\n this.processPaginatedQuerySplits(changed, (token) =>\n this.client.localQueryResultByToken(token),\n );\n\n paginatedQueries = changed.map((token) => ({\n token,\n modification: {\n kind: \"Updated\" as const,\n result: this.localQueryResultByToken(token),\n },\n }));\n }\n\n const extendedTransition: ExtendedTransition = {\n ...transition,\n paginatedQueries,\n };\n\n this.onTransition(extendedTransition);\n }\n\n /**\n * Load more items for a paginated query.\n *\n * This *always* causes a transition, the status of the query\n * has probably changed from \"CanLoadMore\" to \"LoadingMore\".\n * Data might have changed too: maybe a subscription to this page\n * query already exists (unlikely but possible) or this page query\n * has an optimistic update providing some initial data.\n *\n * @internal\n */\n private loadMoreOfPaginatedQuery(\n token: PaginatedQueryToken,\n numItems: number,\n ): boolean {\n this.mustGetPaginatedQuery(token);\n\n const lastPageToken = this.queryTokenForLastPageOfPaginatedQuery(token);\n const lastPageResult = this.client.localQueryResultByToken(lastPageToken);\n\n if (!lastPageResult) {\n // Still loading a page and concurrent loads are not allowed\n return false;\n }\n\n const paginationResult = asPaginationResult(lastPageResult);\n if (paginationResult.isDone) {\n // No more pages available\n return false;\n }\n\n this.addPageToPaginatedQuery(\n token,\n paginationResult.continueCursor,\n numItems,\n );\n\n const loadMoreTransition: ExtendedTransition = {\n timestamp: this.lastTransitionTs,\n reflectedMutations: [],\n queries: [],\n paginatedQueries: [\n {\n token,\n modification: {\n kind: \"Updated\" as const,\n result: this.localQueryResultByToken(token),\n },\n },\n ],\n };\n this.onTransition(loadMoreTransition);\n\n return true;\n }\n\n /**\n * @internal\n */\n private queriesContainingTokens(\n queryTokens: QueryToken[],\n ): PaginatedQueryToken[] {\n if (queryTokens.length === 0) {\n return [];\n }\n\n const changed: PaginatedQueryToken[] = [];\n const queryTokenSet = new Set(queryTokens);\n\n for (const [paginatedToken, paginatedQuery] of this.paginatedQuerySet) {\n for (const pageToken of this.allQueryTokens(paginatedQuery)) {\n if (queryTokenSet.has(pageToken)) {\n changed.push(paginatedToken);\n break;\n }\n }\n }\n\n return changed;\n }\n\n /**\n * @internal\n */\n private processPaginatedQuerySplits(\n changed: PaginatedQueryToken[],\n getResult: (token: QueryToken) => Value | undefined,\n ): void {\n for (const paginatedQueryToken of changed) {\n const paginatedQuery = this.mustGetPaginatedQuery(paginatedQueryToken);\n\n // These properties are all mutable, the destructure here is optional.\n const { ongoingSplits, pageKeyToQuery, pageKeys } = paginatedQuery;\n\n // Check for any completed splits\n for (const [pageKey, [splitKey1, splitKey2]] of ongoingSplits) {\n const bothNewPagesLoaded =\n getResult(pageKeyToQuery.get(splitKey1)!.queryToken) !== undefined &&\n getResult(pageKeyToQuery.get(splitKey2)!.queryToken) !== undefined;\n\n if (bothNewPagesLoaded) {\n this.completePaginatedQuerySplit(\n paginatedQuery,\n pageKey,\n splitKey1,\n splitKey2,\n );\n }\n }\n\n // Check each active page for splits needed\n for (const pageKey of pageKeys) {\n if (ongoingSplits.has(pageKey)) {\n continue; // Already splitting\n }\n\n const pageToken = pageKeyToQuery.get(pageKey)!.queryToken;\n const pageResult = getResult(pageToken);\n if (!pageResult) {\n continue;\n }\n const result = asPaginationResult(pageResult);\n\n // Check if this page needs splitting\n const shouldSplit =\n result.splitCursor &&\n (result.pageStatus === \"SplitRecommended\" ||\n result.pageStatus === \"SplitRequired\" ||\n // This client-driven page splitting condition will change in the future.\n result.page.length > paginatedQuery.options.initialNumItems * 2);\n\n if (shouldSplit) {\n this.splitPaginatedQueryPage(\n paginatedQuery,\n pageKey,\n result.splitCursor!, // we just checked\n result.continueCursor,\n );\n }\n }\n }\n }\n\n private splitPaginatedQueryPage(\n paginatedQuery: LocalPaginatedQuery,\n pageKey: QueryPageKey,\n splitCursor: string,\n continueCursor: string | null,\n ): void {\n const splitKey1 = paginatedQuery.nextPageKey++;\n const splitKey2 = paginatedQuery.nextPageKey++;\n\n const paginationOpts: Value = {\n cursor: continueCursor,\n numItems: paginatedQuery.options.initialNumItems,\n id: paginatedQuery.id,\n };\n\n // First split page: same cursor as original, but add endCursor at splitCursor\n const firstSubscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n {\n ...paginatedQuery.args,\n paginationOpts: {\n ...paginationOpts,\n cursor: null, // Start from beginning for first split\n endCursor: splitCursor,\n },\n },\n );\n paginatedQuery.pageKeyToQuery.set(splitKey1, firstSubscription);\n\n // Second split page: cursor starts at splitCursor, endCursor is the original continueCursor\n const secondSubscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n {\n ...paginatedQuery.args,\n paginationOpts: {\n ...paginationOpts,\n cursor: splitCursor,\n endCursor: continueCursor,\n },\n },\n );\n paginatedQuery.pageKeyToQuery.set(splitKey2, secondSubscription);\n\n paginatedQuery.ongoingSplits.set(pageKey, [splitKey1, splitKey2]);\n }\n\n /**\n * @internal\n */\n private addPageToPaginatedQuery(\n token: PaginatedQueryToken,\n continueCursor: string | null,\n numItems: number,\n ): { queryToken: QueryToken; unsubscribe: () => void } {\n const paginatedQuery = this.mustGetPaginatedQuery(token);\n const pageKey = paginatedQuery.nextPageKey++;\n\n const paginationOpts: Value = {\n cursor: continueCursor,\n numItems,\n id: paginatedQuery.id,\n };\n\n const pageArgs = {\n ...paginatedQuery.args,\n paginationOpts,\n };\n\n const subscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n pageArgs,\n );\n\n paginatedQuery.pageKeys.push(pageKey);\n paginatedQuery.pageKeyToQuery.set(pageKey, subscription);\n return subscription;\n }\n\n private removePaginatedQuerySubscriber(token: PaginatedQueryToken): void {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n return;\n }\n\n paginatedQuery.numSubscribers -= 1;\n if (paginatedQuery.numSubscribers > 0) {\n return;\n }\n\n // Remove all page subscriptions by calling their unsubscribe callbacks\n for (const subscription of paginatedQuery.pageKeyToQuery.values()) {\n subscription.unsubscribe();\n }\n\n this.paginatedQuerySet.delete(token);\n }\n\n private completePaginatedQuerySplit(\n paginatedQuery: LocalPaginatedQuery,\n pageKey: QueryPageKey,\n splitKey1: QueryPageKey,\n splitKey2: QueryPageKey,\n ): void {\n const originalQuery = paginatedQuery.pageKeyToQuery.get(pageKey)!;\n paginatedQuery.pageKeyToQuery.delete(pageKey);\n const pageIndex = paginatedQuery.pageKeys.indexOf(pageKey);\n paginatedQuery.pageKeys.splice(pageIndex, 1, splitKey1, splitKey2);\n paginatedQuery.ongoingSplits.delete(pageKey);\n originalQuery.unsubscribe();\n }\n\n /** The query tokens for all active pages, in result order */\n private activePageQueryTokens(\n paginatedQuery: LocalPaginatedQuery,\n ): QueryToken[] {\n return paginatedQuery.pageKeys.map(\n (pageKey) => paginatedQuery.pageKeyToQuery.get(pageKey)!.queryToken,\n );\n }\n\n private allQueryTokens(paginatedQuery: LocalPaginatedQuery): QueryToken[] {\n return Array.from(paginatedQuery.pageKeyToQuery.values()).map(\n (sub) => sub.queryToken,\n );\n }\n\n private queryTokenForLastPageOfPaginatedQuery(\n token: PaginatedQueryToken,\n ): QueryToken {\n const paginatedQuery = this.mustGetPaginatedQuery(token);\n const lastPageKey =\n paginatedQuery.pageKeys[paginatedQuery.pageKeys.length - 1];\n if (lastPageKey === undefined) {\n throw new Error(`No pages for paginated query ${token}`);\n }\n return paginatedQuery.pageKeyToQuery.get(lastPageKey)!.queryToken;\n }\n\n private mustGetPaginatedQuery(\n token: PaginatedQueryToken,\n ): LocalPaginatedQuery {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n throw new Error(\"paginated query no longer exists for token \" + token);\n }\n return paginatedQuery;\n }\n}\n", "import { validateDeploymentUrl } from \"../common/index.js\";\nimport {\n BaseConvexClient,\n BaseConvexClientOptions,\n MutationOptions,\n PaginatedQueryToken,\n QueryToken,\n UserIdentityAttributes,\n} from \"./index.js\";\nimport {\n FunctionArgs,\n FunctionReference,\n FunctionReturnType,\n PaginationResult,\n} from \"../server/index.js\";\nimport { getFunctionName } from \"../server/api.js\";\nimport { AuthTokenFetcher } from \"./sync/authentication_manager.js\";\nimport { ConnectionState } from \"./sync/client.js\";\nimport {\n ExtendedTransition,\n PaginatedQueryClient,\n} from \"./sync/paginated_query_client.js\";\nimport { PaginatedQueryResult } from \"./sync/pagination.js\";\nimport { serializedQueryTokenIsPaginated } from \"./sync/udf_path_utils.js\";\n\n// In Node.js builds this points to a bundled WebSocket implementation. If no\n// WebSocket implementation is manually specified or globally available,\n// this one is used.\nlet defaultWebSocketConstructor: typeof WebSocket | undefined;\n\n/** internal */\nexport function setDefaultWebSocketConstructor(ws: typeof WebSocket) {\n defaultWebSocketConstructor = ws;\n}\n\nexport type ConvexClientOptions = BaseConvexClientOptions & {\n /**\n * `disabled` makes onUpdate callback registration a no-op and actions,\n * mutations and one-shot queries throw. Setting disabled to true may be\n * useful for server-side rendering, where subscriptions don't make sense.\n */\n disabled?: boolean;\n /**\n * Whether to prompt users in browsers about queued or in-flight mutations.\n * This only works in environments where `window.onbeforeunload` is available.\n *\n * Defaults to true when `window` is defined, otherwise false.\n */\n unsavedChangesWarning?: boolean;\n};\n\n/**\n * Stops callbacks from running.\n *\n * @public\n */\nexport type Unsubscribe<T> = {\n /** Stop calling callback when query results changes. If this is the last listener on this query, stop received updates. */\n (): void;\n /** Stop calling callback when query results changes. If this is the last listener on this query, stop received updates. */\n unsubscribe(): void;\n /** Get the last known value, possibly with local optimistic updates applied. */\n getCurrentValue(): T | undefined;\n /** @internal */\n getQueryLogs(): string[] | undefined;\n};\n\n/**\n * Subscribes to Convex query functions and executes mutations and actions over a WebSocket.\n *\n * Optimistic updates for mutations are not provided for this client.\n * Third party clients may choose to wrap {@link browser.BaseConvexClient} for additional control.\n *\n * ```ts\n * const client = new ConvexClient(\"https://happy-otter-123.convex.cloud\");\n * const unsubscribe = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages[0].body);\n * });\n * ```\n *\n * @public\n */\nexport class ConvexClient {\n private listeners: Set<QueryInfo>;\n private _client: BaseConvexClient | undefined;\n private _paginatedClient: PaginatedQueryClient | undefined;\n // A synthetic server event to run callbacks the first time\n private callNewListenersWithCurrentValuesTimer:\n | ReturnType<typeof setTimeout>\n | undefined;\n private _closed: boolean;\n private _disabled: boolean;\n /**\n * Once closed no registered callbacks will fire again.\n */\n get closed(): boolean {\n return this._closed;\n }\n get client(): BaseConvexClient {\n if (this._client) return this._client;\n throw new Error(\"ConvexClient is disabled\");\n }\n /**\n * @internal\n */\n get paginatedClient(): PaginatedQueryClient {\n if (this._paginatedClient) return this._paginatedClient;\n throw new Error(\"ConvexClient is disabled\");\n }\n get disabled(): boolean {\n return this._disabled;\n }\n\n /**\n * Construct a client and immediately initiate a WebSocket connection to the passed address.\n *\n * @public\n */\n constructor(address: string, options: ConvexClientOptions = {}) {\n if (options.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n const { disabled, ...baseOptions } = options;\n this._closed = false;\n this._disabled = !!disabled;\n if (\n defaultWebSocketConstructor &&\n !(\"webSocketConstructor\" in baseOptions) &&\n typeof WebSocket === \"undefined\"\n ) {\n baseOptions.webSocketConstructor = defaultWebSocketConstructor;\n }\n if (\n typeof window === \"undefined\" &&\n !(\"unsavedChangesWarning\" in baseOptions)\n ) {\n baseOptions.unsavedChangesWarning = false;\n }\n if (!this.disabled) {\n this._client = new BaseConvexClient(\n address,\n () => {}, // NOP, let the paginated query client do it all\n baseOptions,\n );\n this._paginatedClient = new PaginatedQueryClient(\n this._client,\n (transition) => this._transition(transition),\n );\n }\n this.listeners = new Set();\n }\n\n /**\n * Call a callback whenever a new result for a query is received. The callback\n * will run soon after being registered if a result for the query is already\n * in memory.\n *\n * The return value is an {@link Unsubscribe} object which is both a function\n * an an object with properties. Both of the patterns below work with this object:\n *\n *```ts\n * // call the return value as a function\n * const unsubscribe = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages);\n * });\n * unsubscribe();\n *\n * // unpack the return value into its properties\n * const {\n * getCurrentValue,\n * unsubscribe,\n * } = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages);\n * });\n *```\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - The arguments to run the query with.\n * @param callback - Function to call when the query result updates.\n * @param onError - Function to call when the query result updates with an error.\n * If not provided, errors will be thrown instead of calling the callback.\n *\n * @return an {@link Unsubscribe} function to stop calling the onUpdate function.\n */\n onUpdate<Query extends FunctionReference<\"query\">>(\n query: Query,\n args: FunctionArgs<Query>,\n callback: (result: FunctionReturnType<Query>) => unknown,\n onError?: (e: Error) => unknown,\n ): Unsubscribe<Query[\"_returnType\"]> {\n if (this.disabled) {\n return this.createDisabledUnsubscribe<Query[\"_returnType\"]>();\n }\n\n // BaseConvexClient takes care of deduplicating queries subscriptions...\n const { queryToken, unsubscribe } = this.client.subscribe(\n getFunctionName(query),\n args,\n );\n\n // ...but we still need to bookkeep callbacks to actually call them.\n const queryInfo: QueryInfo = {\n queryToken,\n callback,\n onError,\n unsubscribe,\n hasEverRun: false,\n query,\n args,\n paginationOptions: undefined,\n };\n this.listeners.add(queryInfo);\n\n // If the callback is registered for a query with a result immediately available\n // schedule a fake transition to call the callback soon instead of waiting for\n // a new server update (which could take seconds or days).\n if (\n this.queryResultReady(queryToken) &&\n this.callNewListenersWithCurrentValuesTimer === undefined\n ) {\n this.callNewListenersWithCurrentValuesTimer = setTimeout(\n () => this.callNewListenersWithCurrentValues(),\n 0,\n );\n }\n\n const unsubscribeProps: RemoveCallSignature<\n Unsubscribe<Query[\"_returnType\"]>\n > = {\n unsubscribe: () => {\n if (this.closed) {\n // all unsubscribes already ran\n return;\n }\n this.listeners.delete(queryInfo);\n unsubscribe();\n },\n getCurrentValue: () => this.client.localQueryResultByToken(queryToken),\n getQueryLogs: () => this.client.localQueryLogs(queryToken),\n };\n const ret = unsubscribeProps.unsubscribe as Unsubscribe<\n Query[\"_returnType\"]\n >;\n Object.assign(ret, unsubscribeProps);\n return ret;\n }\n\n /**\n * Call a callback whenever a new result for a paginated query is received.\n *\n * This is an experimental preview: the final API may change.\n * In particular, caching behavior, page splitting, and required paginated query options\n * may change.\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - The arguments to run the query with.\n * @param options - Options for the paginated query including initialNumItems and id.\n * @param callback - Function to call when the query result updates.\n * @param onError - Function to call when the query result updates with an error.\n *\n * @return an {@link Unsubscribe} function to stop calling the callback.\n */\n onPaginatedUpdate_experimental<Query extends FunctionReference<\"query\">>(\n query: Query,\n args: FunctionArgs<Query>,\n options: { initialNumItems: number },\n callback: (result: PaginationResult<FunctionReturnType<Query>>) => unknown,\n onError?: (e: Error) => unknown,\n ): Unsubscribe<PaginatedQueryResult<FunctionReturnType<Query>[]>> {\n if (this.disabled) {\n return this.createDisabledUnsubscribe<\n PaginatedQueryResult<FunctionReturnType<Query>>\n >();\n }\n\n const paginationOptions = {\n initialNumItems: options.initialNumItems,\n id: -1,\n };\n\n const { paginatedQueryToken, unsubscribe } = this.paginatedClient.subscribe(\n getFunctionName(query),\n args,\n // Simple client doesn't use IDs, there's no expectation that these queries remain separate.\n paginationOptions,\n );\n\n const queryInfo: QueryInfo = {\n queryToken: paginatedQueryToken,\n callback,\n onError,\n unsubscribe,\n hasEverRun: false,\n query,\n args,\n paginationOptions,\n };\n this.listeners.add(queryInfo);\n\n // If the callback is registered for a query with a result immediately available\n // schedule a fake transition to call the callback soon instead of waiting for\n // a new server update (which could take seconds or days).\n if (\n !!this.paginatedClient.localQueryResultByToken(paginatedQueryToken) &&\n this.callNewListenersWithCurrentValuesTimer === undefined\n ) {\n this.callNewListenersWithCurrentValuesTimer = setTimeout(\n () => this.callNewListenersWithCurrentValues(),\n 0,\n );\n }\n\n const unsubscribeProps: RemoveCallSignature<\n Unsubscribe<PaginatedQueryResult<FunctionReturnType<Query>[]>>\n > = {\n unsubscribe: () => {\n if (this.closed) {\n // all unsubscribes already ran\n return;\n }\n this.listeners.delete(queryInfo);\n unsubscribe();\n },\n getCurrentValue: () => {\n const result = this.paginatedClient.localQueryResult(\n getFunctionName(query),\n args,\n paginationOptions,\n );\n // cast to apply the specific function type\n return result as\n | PaginatedQueryResult<FunctionReturnType<Query>>\n | undefined;\n },\n getQueryLogs: () => [], // Paginated queries don't aggregate their logs\n };\n const ret = unsubscribeProps.unsubscribe as Unsubscribe<\n PaginatedQueryResult<FunctionReturnType<Query>>\n >;\n Object.assign(ret, unsubscribeProps);\n return ret;\n }\n\n // Run all callbacks that have never been run before if they have a query\n // result available now.\n private callNewListenersWithCurrentValues() {\n this.callNewListenersWithCurrentValuesTimer = undefined;\n this._transition({ queries: [], paginatedQueries: [] }, true);\n }\n\n private queryResultReady(queryToken: QueryToken): boolean {\n return this.client.hasLocalQueryResultByToken(queryToken);\n }\n\n private createDisabledUnsubscribe<T>(): Unsubscribe<T> {\n const disabledUnsubscribe = (() => {}) as Unsubscribe<T>;\n const unsubscribeProps: RemoveCallSignature<Unsubscribe<T>> = {\n unsubscribe: disabledUnsubscribe,\n getCurrentValue: () => undefined,\n getQueryLogs: () => undefined,\n };\n Object.assign(disabledUnsubscribe, unsubscribeProps);\n return disabledUnsubscribe;\n }\n\n async close() {\n if (this.disabled) return;\n // prevent pending updates\n this.listeners.clear();\n this._closed = true;\n if (this._paginatedClient) {\n this._paginatedClient = undefined;\n }\n return this.client.close();\n }\n\n /**\n * Get the current JWT auth token and decoded claims.\n */\n getAuth(): { token: string; decoded: Record<string, any> } | undefined {\n if (this.disabled) return;\n return this.client.getCurrentAuthClaims();\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 (typically an OpenID Connect Identity Token)\n * @param onChange - a callback that will be called when the authentication status changes\n */\n setAuth(\n fetchToken: AuthTokenFetcher,\n onChange?: (isAuthenticated: boolean) => void,\n ) {\n if (this.disabled) return;\n this.client.setAuth(\n fetchToken,\n onChange ??\n (() => {\n // Do nothing\n }),\n );\n }\n\n /**\n * @internal\n */\n setAdminAuth(token: string, identity?: UserIdentityAttributes) {\n if (this.closed) {\n throw new Error(\"ConvexClient has already been closed.\");\n }\n if (this.disabled) return;\n this.client.setAdminAuth(token, identity);\n }\n\n /**\n * @internal\n */\n _transition(\n {\n queries,\n paginatedQueries,\n }: Pick<ExtendedTransition, \"queries\" | \"paginatedQueries\">,\n callNewListeners = false,\n ) {\n const updatedQueries = [\n ...queries.map((q) => q.token),\n ...paginatedQueries.map((q) => q.token),\n ];\n\n // Deduping subscriptions happens in the BaseConvexClient, so not much to do here.\n\n // Call all callbacks in the order they were registered\n for (const queryInfo of this.listeners) {\n const { callback, queryToken, onError, hasEverRun } = queryInfo;\n const isPaginatedQuery = serializedQueryTokenIsPaginated(queryToken);\n\n // What does it mean to have a paginated query result ready? I think it's\n // always going to fire immediately.\n const hasResultReady = isPaginatedQuery\n ? !!this.paginatedClient.localQueryResultByToken(queryToken)\n : this.client.hasLocalQueryResultByToken(queryToken);\n\n if (\n updatedQueries.includes(queryToken) ||\n (callNewListeners && !hasEverRun && hasResultReady)\n ) {\n queryInfo.hasEverRun = true;\n let newValue;\n try {\n if (isPaginatedQuery) {\n newValue = this.paginatedClient.localQueryResultByToken(queryToken);\n } else {\n newValue = this.client.localQueryResultByToken(queryToken);\n }\n } catch (error) {\n if (!(error instanceof Error)) throw error;\n if (onError) {\n onError(\n error,\n \"Second argument to onUpdate onError is reserved for later use\",\n );\n } else {\n // Make some noise without unsubscribing or failing to call other callbacks.\n void Promise.reject(error);\n }\n continue;\n }\n callback(\n newValue,\n \"Second argument to onUpdate callback is reserved for later use\",\n );\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.\n * @param options - A {@link MutationOptions} options object for the mutation.\n * @returns A promise of the mutation's result.\n */\n async mutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n args: FunctionArgs<Mutation>,\n options?: MutationOptions,\n ): Promise<Awaited<FunctionReturnType<Mutation>>> {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return await this.client.mutation(getFunctionName(mutation), 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.\n * @returns A promise of the action's result.\n */\n async action<Action extends FunctionReference<\"action\">>(\n action: Action,\n args: FunctionArgs<Action>,\n ): Promise<Awaited<FunctionReturnType<Action>>> {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return await this.client.action(getFunctionName(action), args);\n }\n\n /**\n * Fetch a query result once.\n *\n * @param query - A {@link server.FunctionReference} for the public query\n * to run.\n * @param args - An arguments object for the query.\n * @returns A promise of the query's result.\n */\n async query<Query extends FunctionReference<\"query\">>(\n query: Query,\n args: Query[\"_args\"],\n ): Promise<Awaited<Query[\"_returnType\"]>> {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n const value = this.client.localQueryResult(getFunctionName(query), args) as\n | Awaited<Query[\"_returnType\"]>\n | undefined;\n if (value !== undefined) return Promise.resolve(value);\n\n return new Promise((resolve, reject) => {\n const { unsubscribe } = this.onUpdate(\n query,\n args,\n (value) => {\n unsubscribe();\n resolve(value);\n },\n (e: Error) => {\n unsubscribe();\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 if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return this.client.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 *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(\n cb: (connectionState: ConnectionState) => void,\n ): () => void {\n if (this.disabled) return () => {};\n return this.client.subscribeToConnectionState(cb);\n }\n}\n\n// internal information tracked about each registered callback\ntype QueryInfo = {\n callback: (result: any, meta: unknown) => unknown;\n onError: ((e: Error, meta: unknown) => unknown) | undefined;\n unsubscribe: () => void;\n queryToken: QueryToken | PaginatedQueryToken;\n hasEverRun: boolean;\n // query, args and paginationOptions are just here for debugging, the queryToken is authoritative\n query: FunctionReference<\"query\">;\n args: any;\n paginationOptions: { initialNumItems: number; id: number } | undefined;\n};\n\n// helps to construct objects with a call signature\ntype RemoveCallSignature<T> = Omit<T, never>;\n", "import {\n FunctionReference,\n FunctionReturnType,\n OptionalRestArgs,\n getFunctionName,\n} from \"../server/api.js\";\nimport { parseArgs, validateDeploymentUrl } from \"../common/index.js\";\nimport { version } from \"../index.js\";\nimport {\n ConvexError,\n JSONValue,\n convexToJson,\n jsonToConvex,\n} from \"../values/index.js\";\nimport {\n instantiateDefaultLogger,\n instantiateNoopLogger,\n logForFunction,\n Logger,\n} from \"./logging.js\";\nimport {\n ArgsAndOptions,\n FunctionArgs,\n UserIdentityAttributes,\n} from \"../server/index.js\";\n\nexport const STATUS_CODE_OK = 200;\nexport const STATUS_CODE_BAD_REQUEST = 400;\n// Special custom 5xx HTTP status code to mean that the UDF returned an error.\n//\n// Must match the constant of the same name in the backend.\nexport const STATUS_CODE_UDF_FAILED = 560;\n\n// Allow fetch to be shimmed in for Node.js < 18\nlet specifiedFetch: typeof globalThis.fetch | undefined = undefined;\nexport function setFetch(f: typeof globalThis.fetch) {\n specifiedFetch = f;\n}\n\nexport type HttpMutationOptions = {\n /**\n * Skip the default queue of mutations and run this immediately.\n *\n * This allows the same HttpConvexClient to be used to request multiple\n * mutations in parallel, something not possible with WebSocket-based clients.\n */\n skipQueue: boolean;\n};\n\n/**\n * A Convex client that runs queries and mutations over HTTP.\n *\n * This client is stateful (it has user credentials and queues mutations)\n * so take care to avoid sharing it between requests in a server.\n *\n * This is appropriate for server-side code (like Netlify Lambdas) or non-reactive\n * webapps.\n *\n * @public\n */\nexport class ConvexHttpClient {\n private readonly address: string;\n private auth: string | undefined;\n private adminAuth: string | undefined;\n private encodedTsPromise?: Promise<string>;\n private debug: boolean;\n private fetchOptions?: FetchOptions;\n private fetch?: typeof globalThis.fetch | undefined;\n private logger: Logger;\n private mutationQueue: Array<{\n mutation: FunctionReference<\"mutation\">;\n args: FunctionArgs<any>;\n resolve: (value: any) => void;\n reject: (error: any) => void;\n }> = [];\n private isProcessingQueue: boolean = false;\n\n /**\n * Create a new {@link ConvexHttpClient}.\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 - An object of options.\n * - `skipConvexDeploymentUrlCheck` - Skip validating that the Convex deployment URL looks like\n * `https://happy-animal-123.convex.cloud` or localhost. This can be useful if running a self-hosted\n * Convex backend that uses a different URL.\n * - `logger` - A logger or a boolean. If not provided, logs to the console.\n * You can construct your own logger to customize logging to log elsewhere\n * or not log at all, or use `false` as a shorthand for a no-op logger.\n * A logger is an object with 4 methods: log(), warn(), error(), and logVerbose().\n * These methods can receive multiple arguments of any types, like console.log().\n * - `auth` - A JWT containing identity claims accessible in Convex functions.\n * This identity may expire so it may be necessary to call `setAuth()` later,\n * but for short-lived clients it's convenient to specify this value here.\n * - `fetch` - A custom fetch implementation to use for all HTTP requests made by this client.\n */\n constructor(\n address: string,\n options?: {\n skipConvexDeploymentUrlCheck?: boolean;\n logger?: Logger | boolean;\n auth?: string;\n fetch?: typeof globalThis.fetch;\n },\n ) {\n if (typeof options === \"boolean\") {\n throw new Error(\n \"skipConvexDeploymentUrlCheck as the second argument is no longer supported. Please pass an options object, `{ skipConvexDeploymentUrlCheck: true }`.\",\n );\n }\n const opts = options ?? {};\n if (opts.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n this.logger =\n options?.logger === false\n ? instantiateNoopLogger({ verbose: false })\n : options?.logger !== true && options?.logger\n ? options.logger\n : instantiateDefaultLogger({ verbose: false });\n this.address = address;\n this.debug = true;\n this.auth = undefined;\n this.adminAuth = undefined;\n this.fetch = options?.fetch;\n if (options?.auth) {\n this.setAuth(options.auth);\n }\n }\n\n /**\n * Obtain the {@link ConvexHttpClient}'s URL to its backend.\n * @deprecated Use url, which returns the url without /api at the end.\n *\n * @returns The URL to the Convex backend, including the client's API version.\n */\n backendUrl(): string {\n return `${this.address}/api`;\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 * Set the authentication token to be used for subsequent queries and mutations.\n *\n * Should be called whenever the token changes (i.e. due to expiration and refresh).\n *\n * @param value - JWT-encoded OpenID Connect identity token.\n */\n setAuth(value: string) {\n this.clearAuth();\n this.auth = value;\n }\n\n /**\n * Set admin auth token to allow calling internal queries, mutations, and actions\n * and acting as an identity.\n *\n * @internal\n */\n setAdminAuth(token: string, actingAsIdentity?: UserIdentityAttributes) {\n this.clearAuth();\n if (actingAsIdentity !== undefined) {\n // Encode the identity to a base64 string\n const bytes = new TextEncoder().encode(JSON.stringify(actingAsIdentity));\n const actingAsIdentityEncoded = btoa(String.fromCodePoint(...bytes));\n this.adminAuth = `${token}:${actingAsIdentityEncoded}`;\n } else {\n this.adminAuth = token;\n }\n }\n\n /**\n * Clear the current authentication token if set.\n */\n clearAuth() {\n this.auth = undefined;\n this.adminAuth = undefined;\n }\n\n /**\n * Sets whether the result log lines should be printed on the console or not.\n *\n * @internal\n */\n setDebug(debug: boolean) {\n this.debug = debug;\n }\n\n /**\n * Used to customize the fetch behavior in some runtimes.\n *\n * @internal\n */\n setFetchOptions(fetchOptions: FetchOptions) {\n this.fetchOptions = fetchOptions;\n }\n\n /**\n * This API is experimental: it may change or disappear.\n *\n * Execute a Convex query function at the same timestamp as every other\n * consistent query execution run by this HTTP client.\n *\n * This doesn't make sense for long-lived ConvexHttpClients as Convex\n * backends can read a limited amount into the past: beyond 30 seconds\n * in the past may not be available.\n *\n * Create a new client to use a consistent time.\n *\n * @param name - The name of the query.\n * @param args - The 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 * @deprecated This API is experimental: it may change or disappear.\n */\n async consistentQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgs<Query>\n ): Promise<FunctionReturnType<Query>> {\n const queryArgs = parseArgs(args[0]);\n\n const timestampPromise = this.getTimestamp();\n return await this.queryInner(query, queryArgs, { timestampPromise });\n }\n\n private async getTimestamp() {\n if (this.encodedTsPromise) {\n return this.encodedTsPromise;\n }\n return (this.encodedTsPromise = this.getTimestampInner());\n }\n\n private async getTimestampInner() {\n const localFetch = this.fetch || specifiedFetch || fetch;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n const response = await localFetch(`${this.address}/api/query_ts`, {\n ...this.fetchOptions,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok) {\n throw new Error(await response.text());\n }\n const { ts } = (await response.json()) as { ts: string };\n return ts;\n }\n\n /**\n * Execute a Convex query function.\n *\n * @param name - The name of the query.\n * @param args - The 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 async query<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgs<Query>\n ): Promise<FunctionReturnType<Query>> {\n const queryArgs = parseArgs(args[0]);\n return await this.queryInner(query, queryArgs, {});\n }\n\n private async queryInner<Query extends FunctionReference<\"query\">>(\n query: Query,\n queryArgs: FunctionArgs<Query>,\n options: { timestampPromise?: Promise<string> },\n ): Promise<FunctionReturnType<Query>> {\n const name = getFunctionName(query);\n const args = [convexToJson(queryArgs)];\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n if (this.adminAuth) {\n headers[\"Authorization\"] = `Convex ${this.adminAuth}`;\n } else if (this.auth) {\n headers[\"Authorization\"] = `Bearer ${this.auth}`;\n }\n const localFetch = this.fetch || specifiedFetch || fetch;\n\n const timestamp = options.timestampPromise\n ? await options.timestampPromise\n : undefined;\n\n const body = JSON.stringify({\n path: name,\n format: \"convex_encoded_json\",\n args,\n ...(timestamp ? { ts: timestamp } : {}),\n });\n const endpoint = timestamp\n ? `${this.address}/api/query_at_ts`\n : `${this.address}/api/query`;\n\n const response = await localFetch(endpoint, {\n ...this.fetchOptions,\n body,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {\n throw new Error(await response.text());\n }\n const respJSON = await response.json();\n\n if (this.debug) {\n for (const line of respJSON.logLines ?? []) {\n logForFunction(this.logger, \"info\", \"query\", name, line);\n }\n }\n switch (respJSON.status) {\n case \"success\":\n return jsonToConvex(respJSON.value);\n case \"error\":\n if (respJSON.errorData !== undefined) {\n throw forwardErrorData(\n respJSON.errorData,\n new ConvexError(respJSON.errorMessage),\n );\n }\n throw new Error(respJSON.errorMessage);\n default:\n throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);\n }\n }\n\n private async mutationInner<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n mutationArgs: FunctionArgs<Mutation>,\n ): Promise<FunctionReturnType<Mutation>> {\n const name = getFunctionName(mutation);\n const body = JSON.stringify({\n path: name,\n format: \"convex_encoded_json\",\n args: [convexToJson(mutationArgs)],\n });\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n if (this.adminAuth) {\n headers[\"Authorization\"] = `Convex ${this.adminAuth}`;\n } else if (this.auth) {\n headers[\"Authorization\"] = `Bearer ${this.auth}`;\n }\n const localFetch = this.fetch || specifiedFetch || fetch;\n const response = await localFetch(`${this.address}/api/mutation`, {\n ...this.fetchOptions,\n body,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {\n throw new Error(await response.text());\n }\n const respJSON = await response.json();\n if (this.debug) {\n for (const line of respJSON.logLines ?? []) {\n logForFunction(this.logger, \"info\", \"mutation\", name, line);\n }\n }\n switch (respJSON.status) {\n case \"success\":\n return jsonToConvex(respJSON.value);\n case \"error\":\n if (respJSON.errorData !== undefined) {\n throw forwardErrorData(\n respJSON.errorData,\n new ConvexError(respJSON.errorMessage),\n );\n }\n throw new Error(respJSON.errorMessage);\n default:\n throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);\n }\n }\n\n private async processMutationQueue() {\n if (this.isProcessingQueue) {\n return;\n }\n\n this.isProcessingQueue = true;\n while (this.mutationQueue.length > 0) {\n const { mutation, args, resolve, reject } = this.mutationQueue.shift()!;\n try {\n const result = await this.mutationInner(mutation, args);\n resolve(result);\n } catch (error) {\n reject(error);\n }\n }\n this.isProcessingQueue = false;\n }\n\n private enqueueMutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n args: FunctionArgs<Mutation>,\n ): Promise<FunctionReturnType<Mutation>> {\n return new Promise((resolve, reject) => {\n this.mutationQueue.push({ mutation, args, resolve, reject });\n void this.processMutationQueue();\n });\n }\n\n /**\n * Execute a Convex mutation function. Mutations are queued by default.\n *\n * @param name - The name of the mutation.\n * @param args - The arguments object for the mutation. If this is omitted,\n * the arguments will be `{}`.\n * @param options - An optional object containing\n * @returns A promise of the mutation's result.\n */\n async mutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n ...args: ArgsAndOptions<Mutation, HttpMutationOptions>\n ): Promise<FunctionReturnType<Mutation>> {\n const [fnArgs, options] = args;\n const mutationArgs = parseArgs(fnArgs);\n const queued = !options?.skipQueue;\n\n if (queued) {\n return await this.enqueueMutation(mutation, mutationArgs);\n } else {\n return await this.mutationInner(mutation, mutationArgs);\n }\n }\n\n /**\n * Execute a Convex action function. Actions are not queued.\n *\n * @param name - The name of the action.\n * @param args - The 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 async action<Action extends FunctionReference<\"action\">>(\n action: Action,\n ...args: OptionalRestArgs<Action>\n ): Promise<FunctionReturnType<Action>> {\n const actionArgs = parseArgs(args[0]);\n const name = getFunctionName(action);\n const body = JSON.stringify({\n path: name,\n format: \"convex_encoded_json\",\n args: [convexToJson(actionArgs)],\n });\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n if (this.adminAuth) {\n headers[\"Authorization\"] = `Convex ${this.adminAuth}`;\n } else if (this.auth) {\n headers[\"Authorization\"] = `Bearer ${this.auth}`;\n }\n const localFetch = this.fetch || specifiedFetch || fetch;\n const response = await localFetch(`${this.address}/api/action`, {\n ...this.fetchOptions,\n body,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {\n throw new Error(await response.text());\n }\n const respJSON = await response.json();\n if (this.debug) {\n for (const line of respJSON.logLines ?? []) {\n logForFunction(this.logger, \"info\", \"action\", name, line);\n }\n }\n switch (respJSON.status) {\n case \"success\":\n return jsonToConvex(respJSON.value);\n case \"error\":\n if (respJSON.errorData !== undefined) {\n throw forwardErrorData(\n respJSON.errorData,\n new ConvexError(respJSON.errorMessage),\n );\n }\n throw new Error(respJSON.errorMessage);\n default:\n throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);\n }\n }\n\n /**\n * Execute a Convex function of an unknown type. These function calls are not queued.\n *\n * @param name - The name of the function.\n * @param args - The arguments object for the function. If this is omitted,\n * the arguments will be `{}`.\n * @returns A promise of the function's result.\n *\n * @internal\n */\n async function<\n AnyFunction extends FunctionReference<\"query\" | \"mutation\" | \"action\">,\n >(\n anyFunction: AnyFunction | string,\n componentPath?: string,\n ...args: OptionalRestArgs<AnyFunction>\n ): Promise<FunctionReturnType<AnyFunction>> {\n const functionArgs = parseArgs(args[0]);\n const name =\n typeof anyFunction === \"string\"\n ? anyFunction\n : getFunctionName(anyFunction);\n const body = JSON.stringify({\n componentPath: componentPath,\n path: name,\n format: \"convex_encoded_json\",\n args: convexToJson(functionArgs),\n });\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n if (this.adminAuth) {\n headers[\"Authorization\"] = `Convex ${this.adminAuth}`;\n } else if (this.auth) {\n headers[\"Authorization\"] = `Bearer ${this.auth}`;\n }\n const localFetch = this.fetch || specifiedFetch || fetch;\n const response = await localFetch(`${this.address}/api/function`, {\n ...this.fetchOptions,\n body,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {\n throw new Error(await response.text());\n }\n const respJSON = await response.json();\n if (this.debug) {\n for (const line of respJSON.logLines ?? []) {\n logForFunction(this.logger, \"info\", \"any\", name, line);\n }\n }\n switch (respJSON.status) {\n case \"success\":\n return jsonToConvex(respJSON.value);\n case \"error\":\n if (respJSON.errorData !== undefined) {\n throw forwardErrorData(\n respJSON.errorData,\n new ConvexError(respJSON.errorMessage),\n );\n }\n throw new Error(respJSON.errorMessage);\n default:\n throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);\n }\n }\n}\n\nfunction forwardErrorData(errorData: JSONValue, error: ConvexError<string>) {\n (error as ConvexError<any>).data = jsonToConvex(errorData);\n return error;\n}\n\n/**\n * @internal\n */\ntype FetchOptions = { cache: \"force-cache\" | \"no-store\" };\n"],
|
|
5
|
-
"mappings": "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",
|
|
3
|
+
"sources": ["../browser-bundle.js", "../src/index.ts", "../src/values/base64.ts", "../src/common/index.ts", "../src/values/value.ts", "../src/values/errors.ts", "../src/browser/logging.ts", "../src/browser/sync/udf_path_utils.ts", "../src/browser/sync/local_state.ts", "../src/browser/sync/request_manager.ts", "../src/server/functionName.ts", "../src/server/components/paths.ts", "../src/server/api.ts", "../src/browser/sync/optimistic_updates_impl.ts", "../src/vendor/long.ts", "../src/browser/sync/remote_query_set.ts", "../src/browser/sync/protocol.ts", "../src/browser/sync/web_socket_manager.ts", "../src/browser/sync/session.ts", "../src/vendor/jwt-decode/index.ts", "../src/browser/sync/authentication_manager.ts", "../src/browser/sync/metrics.ts", "../src/browser/sync/client.ts", "../src/browser/sync/pagination.ts", "../src/browser/sync/paginated_query_client.ts", "../src/browser/simple_client.ts", "../src/browser/http_client.ts", "../src/browser/query_options.ts"],
|
|
4
|
+
"sourcesContent": ["// Code exposed in the browser bundle\n\nexport * from \"./src/browser/index.js\";\nexport { anyApi } from \"./src/server/index.js\";\n", "export const version = \"1.35.0\";\n", "/*\nhttps://github.com/beatgammit/base64-js/blob/88957c9943c7e2a0f03cdf73e71d579e433627d3/index.js\nCopyright (c) 2014 Jameson Little\nThe MIT License (MIT)\n*/\n\n// Vendored because this library has no ESM build, and some environments\n// (SvelteKit) are happiest when all dependencies are ESM.\n\nvar lookup: string[] = [];\nvar revLookup: number[] = [];\nvar Arr = Uint8Array;\n\nvar code = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i];\n revLookup[code.charCodeAt(i)] = i;\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup[\"-\".charCodeAt(0)] = 62;\nrevLookup[\"_\".charCodeAt(0)] = 63;\n\nfunction getLens(b64: string) {\n var len = b64.length;\n\n if (len % 4 > 0) {\n throw new Error(\"Invalid string. Length must be a multiple of 4\");\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf(\"=\");\n if (validLen === -1) validLen = len;\n\n var placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4);\n\n return [validLen, placeHoldersLen];\n}\n\n// base64 is 4/3 + up to two characters of the original data\n/** @public */\nexport function byteLength(b64: string): number {\n var lens = getLens(b64);\n var validLen = lens[0];\n var placeHoldersLen = lens[1];\n return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;\n}\n\nfunction _byteLength(_b64: string, validLen: number, placeHoldersLen: number) {\n return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;\n}\n\n/** @public */\nexport function toByteArray(b64: string): Uint8Array {\n var tmp;\n var lens = getLens(b64);\n var validLen = lens[0];\n var placeHoldersLen = lens[1];\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));\n\n var curByte = 0;\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0 ? validLen - 4 : validLen;\n\n var i;\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)];\n arr[curByte++] = (tmp >> 16) & 0xff;\n arr[curByte++] = (tmp >> 8) & 0xff;\n arr[curByte++] = tmp & 0xff;\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4);\n arr[curByte++] = tmp & 0xff;\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2);\n arr[curByte++] = (tmp >> 8) & 0xff;\n arr[curByte++] = tmp & 0xff;\n }\n\n return arr;\n}\n\nfunction tripletToBase64(num: number) {\n return (\n lookup[(num >> 18) & 0x3f] +\n lookup[(num >> 12) & 0x3f] +\n lookup[(num >> 6) & 0x3f] +\n lookup[num & 0x3f]\n );\n}\n\nfunction encodeChunk(uint8: Uint8Array, start: number, end: number) {\n var tmp;\n var output = [];\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xff0000) +\n ((uint8[i + 1] << 8) & 0xff00) +\n (uint8[i + 2] & 0xff);\n output.push(tripletToBase64(tmp));\n }\n return output.join(\"\");\n}\n\n/** @public */\nexport function fromByteArray(uint8: Uint8Array): string {\n var tmp;\n var len = uint8.length;\n var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes\n var parts = [];\n var maxChunkLength = 16383; // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(\n encodeChunk(\n uint8,\n i,\n i + maxChunkLength > len2 ? len2 : i + maxChunkLength,\n ),\n );\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1];\n parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + \"==\");\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1];\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3f] +\n lookup[(tmp << 2) & 0x3f] +\n \"=\",\n );\n }\n\n return parts.join(\"\");\n}\n\nexport function fromByteArrayUrlSafeNoPadding(uint8: Uint8Array): string {\n return fromByteArray(uint8)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n}\n", "import type { Value } from \"../values/value.js\";\n\n/**\n * Validate that the arguments to a Convex function are an object, defaulting\n * `undefined` to `{}`.\n */\nexport function parseArgs(\n args: Record<string, Value> | undefined,\n): Record<string, Value> {\n if (args === undefined) {\n return {};\n }\n if (!isSimpleObject(args)) {\n throw new Error(\n `The arguments to a Convex function must be an object. Received: ${\n args as any\n }`,\n );\n }\n return args;\n}\n\nexport function validateDeploymentUrl(deploymentUrl: string) {\n // Don't use things like `new URL(deploymentUrl).hostname` since these aren't\n // supported by React Native's JS environment\n if (typeof deploymentUrl === \"undefined\") {\n throw new Error(\n `Client created with undefined deployment address. If you used an environment variable, check that it's set.`,\n );\n }\n if (typeof deploymentUrl !== \"string\") {\n throw new Error(\n `Invalid deployment address: found ${deploymentUrl as any}\".`,\n );\n }\n if (\n !(deploymentUrl.startsWith(\"http:\") || deploymentUrl.startsWith(\"https:\"))\n ) {\n throw new Error(\n `Invalid deployment address: Must start with \"https://\" or \"http://\". Found \"${deploymentUrl}\".`,\n );\n }\n\n // Most clients should connect to \".convex.cloud\". But we also support localhost and\n // custom custom. We validate the deployment url is a valid url, which is the most\n // common failure pattern.\n try {\n new URL(deploymentUrl);\n } catch {\n throw new Error(\n `Invalid deployment address: \"${deploymentUrl}\" is not a valid URL. If you believe this URL is correct, use the \\`skipConvexDeploymentUrlCheck\\` option to bypass this.`,\n );\n }\n\n // If a user uses .convex.site, this is very likely incorrect.\n if (deploymentUrl.endsWith(\".convex.site\")) {\n throw new Error(\n `Invalid deployment address: \"${deploymentUrl}\" ends with .convex.site, which is used for HTTP Actions. Convex deployment URLs typically end with .convex.cloud? If you believe this URL is correct, use the \\`skipConvexDeploymentUrlCheck\\` option to bypass this.`,\n );\n }\n}\n\n/**\n * Check whether a value is a plain old JavaScript object.\n */\nexport function isSimpleObject(value: unknown) {\n const isObject = typeof value === \"object\";\n const prototype = Object.getPrototypeOf(value);\n const isSimple =\n prototype === null ||\n prototype === Object.prototype ||\n // Objects generated from other contexts (e.g. across Node.js `vm` modules) will not satisfy the previous\n // conditions but are still simple objects.\n prototype?.constructor?.name === \"Object\";\n return isObject && isSimple;\n}\n", "/**\n * Utilities for working with values stored in Convex.\n *\n * You can see the full set of supported types at\n * [Types](https://docs.convex.dev/using/types).\n * @module\n */\nimport * as Base64 from \"./base64.js\";\nimport { isSimpleObject } from \"../common/index.js\";\n\nconst LITTLE_ENDIAN = true;\n// This code is used by code that may not have bigint literals.\nconst MIN_INT64 = BigInt(\"-9223372036854775808\");\nconst MAX_INT64 = BigInt(\"9223372036854775807\");\nconst ZERO = BigInt(\"0\");\nconst EIGHT = BigInt(\"8\");\nconst TWOFIFTYSIX = BigInt(\"256\");\n\n/**\n * The type of JavaScript values serializable to JSON.\n *\n * @public\n */\nexport type JSONValue =\n | null\n | boolean\n | number\n | string\n | JSONValue[]\n | { [key: string]: JSONValue };\n\n/**\n * An identifier for a document in Convex.\n *\n * Convex documents are uniquely identified by their `Id`, which is accessible\n * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/database/document-ids).\n *\n * Documents can be loaded using `db.get(tableName, id)` in query and mutation functions.\n *\n * IDs are base 32 encoded strings which are URL safe.\n *\n * IDs are just strings at runtime, but this type can be used to distinguish them from other\n * strings at compile time.\n *\n * If you're using code generation, use the `Id` type generated for your data model in\n * `convex/_generated/dataModel.d.ts`.\n *\n * @typeParam TableName - A string literal type of the table name (like \"users\").\n *\n * @public\n */\nexport type Id<TableName extends string> = string & { __tableName: TableName };\n\n/**\n * A value supported by Convex.\n *\n * Values can be:\n * - stored inside of documents.\n * - used as arguments and return types to queries and mutation functions.\n *\n * You can see the full set of supported types at\n * [Types](https://docs.convex.dev/using/types).\n *\n * @public\n */\nexport type Value =\n | null\n | bigint\n | number\n | boolean\n | string\n | ArrayBuffer\n | Value[]\n | { [key: string]: undefined | Value };\n\n/**\n * The types of {@link Value} that can be used to represent numbers.\n *\n * @public\n */\nexport type NumericValue = bigint | number;\n\nfunction isSpecial(n: number) {\n return Number.isNaN(n) || !Number.isFinite(n) || Object.is(n, -0);\n}\n\nexport function slowBigIntToBase64(value: bigint): string {\n // the conversion is easy if we pretend it's unsigned\n if (value < ZERO) {\n value -= MIN_INT64 + MIN_INT64;\n }\n let hex = value.toString(16);\n if (hex.length % 2 === 1) hex = \"0\" + hex;\n\n const bytes = new Uint8Array(new ArrayBuffer(8));\n let i = 0;\n for (const hexByte of hex.match(/.{2}/g)!.reverse()) {\n bytes.set([parseInt(hexByte, 16)], i++);\n value >>= EIGHT;\n }\n return Base64.fromByteArray(bytes);\n}\n\nexport function slowBase64ToBigInt(encoded: string): bigint {\n const integerBytes = Base64.toByteArray(encoded);\n if (integerBytes.byteLength !== 8) {\n throw new Error(\n `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`,\n );\n }\n let value = ZERO;\n let power = ZERO;\n for (const byte of integerBytes) {\n value += BigInt(byte) * TWOFIFTYSIX ** power;\n power++;\n }\n if (value > MAX_INT64) {\n value += MIN_INT64 + MIN_INT64;\n }\n return value;\n}\n\nexport function modernBigIntToBase64(value: bigint): string {\n if (value < MIN_INT64 || MAX_INT64 < value) {\n throw new Error(\n `BigInt ${value} does not fit into a 64-bit signed integer.`,\n );\n }\n const buffer = new ArrayBuffer(8);\n new DataView(buffer).setBigInt64(0, value, true);\n return Base64.fromByteArray(new Uint8Array(buffer));\n}\n\nexport function modernBase64ToBigInt(encoded: string): bigint {\n const integerBytes = Base64.toByteArray(encoded);\n if (integerBytes.byteLength !== 8) {\n throw new Error(\n `Received ${integerBytes.byteLength} bytes, expected 8 for $integer`,\n );\n }\n const intBytesView = new DataView(integerBytes.buffer);\n return intBytesView.getBigInt64(0, true);\n}\n\n// Fall back to a slower version on Safari 14 which lacks these APIs.\nexport const bigIntToBase64 = (DataView.prototype as any).setBigInt64\n ? modernBigIntToBase64\n : slowBigIntToBase64;\nexport const base64ToBigInt = (DataView.prototype as any).getBigInt64\n ? modernBase64ToBigInt\n : slowBase64ToBigInt;\n\nconst MAX_IDENTIFIER_LEN = 1024;\n\nfunction validateObjectField(k: string) {\n if (k.length > MAX_IDENTIFIER_LEN) {\n throw new Error(\n `Field name ${k} exceeds maximum field name length ${MAX_IDENTIFIER_LEN}.`,\n );\n }\n if (k.startsWith(\"$\")) {\n throw new Error(`Field name ${k} starts with a '$', which is reserved.`);\n }\n for (let i = 0; i < k.length; i += 1) {\n const charCode = k.charCodeAt(i);\n // Non-control ASCII characters\n if (charCode < 32 || charCode >= 127) {\n throw new Error(\n `Field name ${k} has invalid character '${k[i]}': Field names can only contain non-control ASCII characters`,\n );\n }\n }\n}\n\n/**\n * Parse a Convex value from its JSON representation.\n *\n * This function will deserialize serialized Int64s to `BigInt`s, Bytes to `ArrayBuffer`s etc.\n *\n * To learn more about Convex values, see [Types](https://docs.convex.dev/using/types).\n *\n * @param value - The JSON representation of a Convex value previously created with {@link convexToJson}.\n * @returns The JavaScript representation of the Convex value.\n *\n * @public\n */\nexport function jsonToConvex(value: JSONValue): Value {\n if (value === null) {\n return value;\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((value) => jsonToConvex(value));\n }\n if (typeof value !== \"object\") {\n throw new Error(`Unexpected type of ${value as any}`);\n }\n const entries = Object.entries(value);\n if (entries.length === 1) {\n const key = entries[0][0];\n if (key === \"$bytes\") {\n if (typeof value.$bytes !== \"string\") {\n throw new Error(`Malformed $bytes field on ${value as any}`);\n }\n return Base64.toByteArray(value.$bytes).buffer;\n }\n if (key === \"$integer\") {\n if (typeof value.$integer !== \"string\") {\n throw new Error(`Malformed $integer field on ${value as any}`);\n }\n return base64ToBigInt(value.$integer);\n }\n if (key === \"$float\") {\n if (typeof value.$float !== \"string\") {\n throw new Error(`Malformed $float field on ${value as any}`);\n }\n const floatBytes = Base64.toByteArray(value.$float);\n if (floatBytes.byteLength !== 8) {\n throw new Error(\n `Received ${floatBytes.byteLength} bytes, expected 8 for $float`,\n );\n }\n const floatBytesView = new DataView(floatBytes.buffer);\n const float = floatBytesView.getFloat64(0, LITTLE_ENDIAN);\n if (!isSpecial(float)) {\n throw new Error(`Float ${float} should be encoded as a number`);\n }\n return float;\n }\n if (key === \"$set\") {\n throw new Error(\n `Received a Set which is no longer supported as a Convex type.`,\n );\n }\n if (key === \"$map\") {\n throw new Error(\n `Received a Map which is no longer supported as a Convex type.`,\n );\n }\n }\n const out: { [key: string]: Value } = {};\n for (const [k, v] of Object.entries(value)) {\n validateObjectField(k);\n out[k] = jsonToConvex(v);\n }\n return out;\n}\n\nconst MAX_VALUE_FOR_ERROR_LEN = 16384;\n\nexport function stringifyValueForError(value: any) {\n const str = JSON.stringify(value, (_key, value) => {\n if (value === undefined) {\n // By default `JSON.stringify` converts undefined, functions, symbols,\n // Infinity, and NaN to null which produces a confusing error message.\n // We deal with `undefined` specifically because it's the most common.\n // Ideally we'd use a pretty-printing library that prints `undefined`\n // (no quotes), but it might not be worth the bundle size cost.\n return \"undefined\";\n }\n if (typeof value === \"bigint\") {\n // `JSON.stringify` throws on bigints by default.\n return `${value.toString()}n`;\n }\n return value;\n });\n if (str.length > MAX_VALUE_FOR_ERROR_LEN) {\n const rest = \"[...truncated]\";\n let truncateAt = MAX_VALUE_FOR_ERROR_LEN - rest.length;\n const codePoint = str.codePointAt(truncateAt - 1);\n if (codePoint !== undefined && codePoint > 0xffff) {\n // don't split a surrogate pair in half\n truncateAt -= 1;\n }\n return str.substring(0, truncateAt) + rest;\n }\n return str;\n}\n\nfunction convexToJsonInternal(\n value: Value,\n originalValue: Value,\n context: string,\n includeTopLevelUndefined: boolean,\n): JSONValue {\n if (value === undefined) {\n const contextText =\n context &&\n ` (present at path ${context} in original object ${stringifyValueForError(\n originalValue,\n )})`;\n throw new Error(\n `undefined is not a valid Convex value${contextText}. To learn about Convex's supported types, see https://docs.convex.dev/using/types.`,\n );\n }\n if (value === null) {\n return value;\n }\n if (typeof value === \"bigint\") {\n if (value < MIN_INT64 || MAX_INT64 < value) {\n throw new Error(\n `BigInt ${value} does not fit into a 64-bit signed integer.`,\n );\n }\n return { $integer: bigIntToBase64(value) };\n }\n if (typeof value === \"number\") {\n if (isSpecial(value)) {\n const buffer = new ArrayBuffer(8);\n new DataView(buffer).setFloat64(0, value, LITTLE_ENDIAN);\n return { $float: Base64.fromByteArray(new Uint8Array(buffer)) };\n } else {\n return value;\n }\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (value instanceof ArrayBuffer) {\n return { $bytes: Base64.fromByteArray(new Uint8Array(value)) };\n }\n if (Array.isArray(value)) {\n return value.map((value, i) =>\n convexToJsonInternal(value, originalValue, context + `[${i}]`, false),\n );\n }\n if (value instanceof Set) {\n throw new Error(\n errorMessageForUnsupportedType(context, \"Set\", [...value], originalValue),\n );\n }\n if (value instanceof Map) {\n throw new Error(\n errorMessageForUnsupportedType(context, \"Map\", [...value], originalValue),\n );\n }\n\n if (!isSimpleObject(value)) {\n const theType = value?.constructor?.name;\n const typeName = theType ? `${theType} ` : \"\";\n throw new Error(\n errorMessageForUnsupportedType(context, typeName, value, originalValue),\n );\n }\n\n const out: { [key: string]: JSONValue } = {};\n const entries = Object.entries(value);\n entries.sort(([k1, _v1], [k2, _v2]) => (k1 === k2 ? 0 : k1 < k2 ? -1 : 1));\n for (const [k, v] of entries) {\n if (v !== undefined) {\n validateObjectField(k);\n out[k] = convexToJsonInternal(v, originalValue, context + `.${k}`, false);\n } else if (includeTopLevelUndefined) {\n validateObjectField(k);\n out[k] = convexOrUndefinedToJsonInternal(\n v,\n originalValue,\n context + `.${k}`,\n );\n }\n }\n return out;\n}\n\nfunction errorMessageForUnsupportedType(\n context: string,\n typeName: string,\n value: any,\n originalValue: any,\n) {\n if (context) {\n return `${typeName}${stringifyValueForError(\n value,\n )} is not a supported Convex type (present at path ${context} in original object ${stringifyValueForError(\n originalValue,\n )}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.`;\n } else {\n return `${typeName}${stringifyValueForError(\n value,\n )} is not a supported Convex type.`;\n }\n}\n\n// convexOrUndefinedToJsonInternal wrapper exists so we can pipe through the\n// `originalValue` and `context` through for better error messaging.\nfunction convexOrUndefinedToJsonInternal(\n value: Value | undefined,\n originalValue: Value | undefined,\n context: string,\n): JSONValue {\n if (value === undefined) {\n return { $undefined: null };\n } else {\n if (originalValue === undefined) {\n // This should not happen.\n throw new Error(\n `Programming error. Current value is ${stringifyValueForError(\n value,\n )} but original value is undefined`,\n );\n }\n return convexToJsonInternal(value, originalValue, context, false);\n }\n}\n\n/**\n * Convert a Convex value to its JSON representation.\n *\n * Use {@link jsonToConvex} to recreate the original value.\n *\n * To learn more about Convex values, see [Types](https://docs.convex.dev/using/types).\n *\n * @param value - A Convex value to convert into JSON.\n * @returns The JSON representation of `value`.\n *\n * @public\n */\nexport function convexToJson(value: Value): JSONValue {\n return convexToJsonInternal(value, value, \"\", false);\n}\n\n// Convert a Convex value or `undefined` into its JSON representation.\n// `undefined` is used in filters to represent a missing object field.\nexport function convexOrUndefinedToJson(value: Value | undefined): JSONValue {\n return convexOrUndefinedToJsonInternal(value, value, \"\");\n}\n\n/**\n * Similar to convexToJson but also serializes top level undefined fields\n * using convexOrUndefinedToJson().\n *\n * @param value - A Convex value to convert into JSON.\n * @returns The JSON representation of `value`.\n */\nexport function patchValueToJson(value: Value): JSONValue {\n return convexToJsonInternal(value, value, \"\", true);\n}\n", "import { Value, stringifyValueForError } from \"./value.js\";\n\nconst IDENTIFYING_FIELD = Symbol.for(\"ConvexError\");\n\nexport class ConvexError<TData extends Value> extends Error {\n name = \"ConvexError\";\n data: TData;\n [IDENTIFYING_FIELD] = true;\n\n constructor(data: TData) {\n super(typeof data === \"string\" ? data : stringifyValueForError(data));\n this.data = data;\n }\n}\n", "/* eslint-disable no-console */ // This is the one file where we can `console.log` for the default logger implementation.\nimport { ConvexError, Value } from \"../values/index.js\";\nimport { FunctionFailure } from \"./sync/function_result.js\";\n\n// This is blue #9 from https://www.radix-ui.com/docs/colors/palette-composition/the-scales\n// It must look good in both light and dark mode.\nconst INFO_COLOR = \"color:rgb(0, 145, 255)\";\n\nexport type UdfType = \"query\" | \"mutation\" | \"action\" | \"any\";\n\nfunction prefix_for_source(source: UdfType) {\n switch (source) {\n case \"query\":\n return \"Q\";\n case \"mutation\":\n return \"M\";\n case \"action\":\n return \"A\";\n case \"any\":\n return \"?\";\n }\n}\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/**\n * A logger that can be used to log messages. By default, this is a wrapper\n * around `console`, but can be configured to not log at all or to log somewhere\n * else.\n */\nexport type Logger = {\n logVerbose(...args: any[]): void;\n log(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n};\n\nexport class DefaultLogger implements Logger {\n private _onLogLineFuncs: Record<\n string,\n (level: LogLevel, ...args: any[]) => void\n >;\n private _verbose: boolean;\n\n constructor(options: { verbose: boolean }) {\n this._onLogLineFuncs = {};\n this._verbose = options.verbose;\n }\n\n addLogLineListener(\n func: (level: LogLevel, ...args: any[]) => void,\n ): () => void {\n let id = Math.random().toString(36).substring(2, 15);\n for (let i = 0; i < 10; i++) {\n if (this._onLogLineFuncs[id] === undefined) {\n break;\n }\n id = Math.random().toString(36).substring(2, 15);\n }\n this._onLogLineFuncs[id] = func;\n return () => {\n delete this._onLogLineFuncs[id];\n };\n }\n\n logVerbose(...args: any[]) {\n if (this._verbose) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"debug\", `${new Date().toISOString()}`, ...args);\n }\n }\n }\n\n log(...args: any[]) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"info\", ...args);\n }\n }\n\n warn(...args: any[]) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"warn\", ...args);\n }\n }\n\n error(...args: any[]) {\n for (const func of Object.values(this._onLogLineFuncs)) {\n func(\"error\", ...args);\n }\n }\n}\n\nexport function instantiateDefaultLogger(options: {\n verbose: boolean;\n}): Logger {\n const logger = new DefaultLogger(options);\n logger.addLogLineListener((level, ...args) => {\n switch (level) {\n case \"debug\":\n console.debug(...args);\n break;\n case \"info\":\n console.log(...args);\n break;\n case \"warn\":\n console.warn(...args);\n break;\n case \"error\":\n console.error(...args);\n break;\n default: {\n level satisfies never;\n console.log(...args);\n }\n }\n });\n return logger;\n}\n\nexport function instantiateNoopLogger(options: { verbose: boolean }): Logger {\n return new DefaultLogger(options);\n}\n\nexport function logForFunction(\n logger: Logger,\n type: \"info\" | \"error\",\n source: UdfType,\n udfPath: string,\n message: string | { errorData: Value },\n) {\n const prefix = prefix_for_source(source);\n\n if (typeof message === \"object\") {\n message = `ConvexError ${JSON.stringify(message.errorData, null, 2)}`;\n }\n if (type === \"info\") {\n const match = message.match(/^\\[.*?\\] /);\n if (match === null) {\n logger.error(\n `[CONVEX ${prefix}(${udfPath})] Could not parse console.log`,\n );\n return;\n }\n const level = message.slice(1, match[0].length - 2);\n const args = message.slice(match[0].length);\n\n logger.log(`%c[CONVEX ${prefix}(${udfPath})] [${level}]`, INFO_COLOR, args);\n } else {\n logger.error(`[CONVEX ${prefix}(${udfPath})] ${message}`);\n }\n}\n\nexport function logFatalError(logger: Logger, message: string): Error {\n const errorMessage = `[CONVEX FATAL ERROR] ${message}`;\n logger.error(errorMessage);\n return new Error(errorMessage);\n}\n\nexport function createHybridErrorStacktrace(\n source: UdfType,\n udfPath: string,\n result: FunctionFailure,\n): string {\n const prefix = prefix_for_source(source);\n return `[CONVEX ${prefix}(${udfPath})] ${result.errorMessage}\\n Called by client`;\n}\n\nexport function forwardData(\n result: FunctionFailure,\n error: ConvexError<string>,\n) {\n (error as ConvexError<any>).data = result.errorData;\n return error;\n}\n", "import { convexToJson, Value } from \"../../values/index.js\";\n\nexport function canonicalizeUdfPath(udfPath: string): string {\n const pieces = udfPath.split(\":\");\n let moduleName: string;\n let functionName: string;\n if (pieces.length === 1) {\n moduleName = pieces[0];\n functionName = \"default\";\n } else {\n moduleName = pieces.slice(0, pieces.length - 1).join(\":\");\n functionName = pieces[pieces.length - 1];\n }\n if (moduleName.endsWith(\".js\")) {\n moduleName = moduleName.slice(0, -3);\n }\n return `${moduleName}:${functionName}`;\n}\n\n/**\n * The serialization here is not stable, these strings never make it outside the client.\n */\n\n/**\n * A string representing the name and arguments of a query.\n *\n * This is used by the {@link BaseConvexClient}.\n *\n * @public\n */\nexport type QueryToken = string & { __queryToken: true };\n\n/**\n * A string representing the name and arguments of a paginated query.\n *\n * This is a specialized form of QueryToken used for paginated queries.\n */\nexport type PaginatedQueryToken = QueryToken & { __paginatedQueryToken: true };\n\nexport function serializePathAndArgs(\n udfPath: string,\n args: Record<string, Value>,\n): QueryToken {\n return JSON.stringify({\n udfPath: canonicalizeUdfPath(udfPath),\n args: convexToJson(args),\n }) as QueryToken;\n}\n\nexport function serializePaginatedPathAndArgs(\n udfPath: string,\n args: Record<string, Value>, // args WITHOUT paginationOpts\n options: { initialNumItems: number; id: number },\n): PaginatedQueryToken {\n const { initialNumItems, id } = options;\n const result = JSON.stringify({\n type: \"paginated\",\n udfPath: canonicalizeUdfPath(udfPath),\n args: convexToJson(args),\n options: convexToJson({ initialNumItems, id }),\n }) as PaginatedQueryToken;\n return result;\n}\n\nexport function serializedQueryTokenIsPaginated(\n token: QueryToken | PaginatedQueryToken,\n): token is PaginatedQueryToken {\n return JSON.parse(token).type === \"paginated\";\n}\n", "/**\n * The local state of the client:\n * - which queries are subscribed to\n * - the \"Query Set Version,\" used to produce QuerySetModification messages\n * - the current auth token and \"Identity Version\"\n *\n * Local state does not include:\n * - query results (see RemoteQuerySet)\n * - locally made \"optimistic update\" modifications to query results (see OptimisticQueryResults)\n * - any query results at all\n **/\n\nimport { convexToJson, Value } from \"../../values/index.js\";\nimport {\n AddQuery,\n RemoveQuery,\n QueryId,\n QuerySetModification,\n QuerySetVersion,\n IdentityVersion,\n Authenticate,\n QueryJournal,\n Transition,\n AdminAuthentication,\n UserIdentityAttributes,\n} from \"./protocol.js\";\nimport {\n canonicalizeUdfPath,\n QueryToken,\n serializePathAndArgs,\n} from \"./udf_path_utils.js\";\n\ntype LocalQuery = {\n id: QueryId;\n canonicalizedUdfPath: string;\n args: Record<string, Value>;\n numSubscribers: number;\n journal?: QueryJournal | undefined;\n componentPath?: string | undefined;\n};\n\nexport type AuthState =\n | {\n tokenType: \"User\";\n value: string;\n }\n | {\n tokenType: \"Admin\";\n value: string;\n impersonating?: UserIdentityAttributes | undefined;\n };\n\nexport class LocalSyncState {\n private nextQueryId: QueryId;\n private querySetVersion: QuerySetVersion;\n private readonly querySet: Map<QueryToken, LocalQuery>;\n private readonly queryIdToToken: Map<QueryId, QueryToken>;\n private identityVersion: IdentityVersion;\n private auth: AuthState | undefined;\n private readonly outstandingQueriesOlderThanRestart: Set<QueryId>;\n private outstandingAuthOlderThanRestart: boolean;\n private paused: boolean;\n private pendingQuerySetModifications: Map<QueryId, AddQuery | RemoveQuery>;\n\n constructor() {\n this.nextQueryId = 0;\n this.querySetVersion = 0;\n this.identityVersion = 0;\n this.querySet = new Map();\n this.queryIdToToken = new Map();\n this.outstandingQueriesOlderThanRestart = new Set();\n this.outstandingAuthOlderThanRestart = false;\n this.paused = false;\n this.pendingQuerySetModifications = new Map();\n }\n\n hasSyncedPastLastReconnect(): boolean {\n return (\n this.outstandingQueriesOlderThanRestart.size === 0 &&\n !this.outstandingAuthOlderThanRestart\n );\n }\n\n markAuthCompletion() {\n this.outstandingAuthOlderThanRestart = false;\n }\n\n subscribe(\n udfPath: string,\n args: Record<string, Value>,\n journal?: QueryJournal | undefined,\n componentPath?: string | undefined,\n ): {\n queryToken: QueryToken;\n modification: QuerySetModification | null;\n unsubscribe: () => QuerySetModification | null;\n } {\n const canonicalizedUdfPath = canonicalizeUdfPath(udfPath);\n const queryToken = serializePathAndArgs(canonicalizedUdfPath, args);\n\n const existingEntry = this.querySet.get(queryToken);\n\n if (existingEntry !== undefined) {\n existingEntry.numSubscribers += 1;\n return {\n queryToken,\n modification: null,\n unsubscribe: () => this.removeSubscriber(queryToken),\n };\n } else {\n const queryId = this.nextQueryId++;\n const query: LocalQuery = {\n id: queryId,\n canonicalizedUdfPath,\n args,\n numSubscribers: 1,\n journal,\n componentPath,\n };\n this.querySet.set(queryToken, query);\n this.queryIdToToken.set(queryId, queryToken);\n\n const baseVersion = this.querySetVersion;\n const newVersion = this.querySetVersion + 1;\n\n const add: AddQuery = {\n type: \"Add\",\n queryId,\n udfPath: canonicalizedUdfPath,\n args: [convexToJson(args)],\n journal,\n componentPath,\n };\n\n if (this.paused) {\n this.pendingQuerySetModifications.set(queryId, add);\n } else {\n this.querySetVersion = newVersion;\n }\n\n const modification: QuerySetModification = {\n type: \"ModifyQuerySet\",\n baseVersion,\n newVersion,\n modifications: [add],\n };\n return {\n queryToken,\n modification,\n unsubscribe: () => this.removeSubscriber(queryToken),\n };\n }\n }\n\n transition(transition: Transition) {\n for (const modification of transition.modifications) {\n switch (modification.type) {\n case \"QueryUpdated\":\n case \"QueryFailed\": {\n this.outstandingQueriesOlderThanRestart.delete(modification.queryId);\n const journal = modification.journal;\n if (journal !== undefined) {\n const queryToken = this.queryIdToToken.get(modification.queryId);\n // We may have already unsubscribed to this query by the time the server\n // sends us the journal. If so, just ignore it.\n if (queryToken !== undefined) {\n this.querySet.get(queryToken)!.journal = journal;\n }\n }\n\n break;\n }\n case \"QueryRemoved\": {\n this.outstandingQueriesOlderThanRestart.delete(modification.queryId);\n break;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n modification satisfies never;\n throw new Error(`Invalid modification ${(modification as any).type}`);\n }\n }\n }\n }\n\n queryId(udfPath: string, args: Record<string, Value>): QueryId | null {\n const canonicalizedUdfPath = canonicalizeUdfPath(udfPath);\n const queryToken = serializePathAndArgs(canonicalizedUdfPath, args);\n const existingEntry = this.querySet.get(queryToken);\n if (existingEntry !== undefined) {\n return existingEntry.id;\n }\n return null;\n }\n\n isCurrentOrNewerAuthVersion(version: IdentityVersion): boolean {\n return version >= this.identityVersion;\n }\n\n getAuth(): AuthState | undefined {\n return this.auth;\n }\n\n setAuth(value: string): Authenticate {\n this.auth = {\n tokenType: \"User\" as const,\n value: value,\n };\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n baseVersion: baseVersion,\n ...this.auth,\n };\n }\n\n setAdminAuth(\n value: string,\n actingAs?: UserIdentityAttributes,\n ): AdminAuthentication {\n const auth: typeof this.auth & {\n tokenType: \"Admin\";\n } = {\n tokenType: \"Admin\",\n value,\n impersonating: actingAs,\n };\n this.auth = auth;\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n baseVersion: baseVersion,\n ...auth,\n };\n }\n\n clearAuth(): Authenticate {\n this.auth = undefined;\n this.markAuthCompletion();\n const baseVersion = this.identityVersion;\n if (!this.paused) {\n this.identityVersion = baseVersion + 1;\n }\n return {\n type: \"Authenticate\",\n tokenType: \"None\",\n baseVersion: baseVersion,\n };\n }\n\n hasAuth(): boolean {\n return !!this.auth;\n }\n\n isNewAuth(value: string): boolean {\n return this.auth?.value !== value;\n }\n\n queryPath(queryId: QueryId): string | null {\n const pathAndArgs = this.queryIdToToken.get(queryId);\n if (pathAndArgs) {\n return this.querySet.get(pathAndArgs)!.canonicalizedUdfPath;\n }\n return null;\n }\n\n queryArgs(queryId: QueryId): Record<string, Value> | null {\n const pathAndArgs = this.queryIdToToken.get(queryId);\n if (pathAndArgs) {\n return this.querySet.get(pathAndArgs)!.args;\n }\n return null;\n }\n\n queryToken(queryId: QueryId): QueryToken | null {\n return this.queryIdToToken.get(queryId) ?? null;\n }\n\n queryJournal(queryToken: QueryToken): QueryJournal | undefined {\n return this.querySet.get(queryToken)?.journal;\n }\n\n restart(): [QuerySetModification, (Authenticate | undefined)?] {\n // Restart works whether we are paused or unpaused.\n // The `this.pendingQuerySetModifications` is not used\n // when restarting as the AddQuery and RemoveQuery are computed\n // from scratch, based on the old remote query results, here.\n this.unpause();\n\n this.outstandingQueriesOlderThanRestart.clear();\n const modifications = [];\n for (const localQuery of this.querySet.values()) {\n const add: AddQuery = {\n type: \"Add\",\n queryId: localQuery.id,\n udfPath: localQuery.canonicalizedUdfPath,\n args: [convexToJson(localQuery.args)],\n journal: localQuery.journal,\n componentPath: localQuery.componentPath,\n };\n modifications.push(add);\n\n // Track all re-sent queries as outstanding so the backoff retry\n // counter doesn't reset until the server has re-confirmed results\n // for every active query.\n this.outstandingQueriesOlderThanRestart.add(localQuery.id);\n }\n this.querySetVersion = 1;\n const querySet: QuerySetModification = {\n type: \"ModifyQuerySet\",\n baseVersion: 0,\n newVersion: 1,\n modifications,\n };\n // If there's no auth, no need to send an update as the server will also start with an unknown identity.\n if (!this.auth) {\n this.identityVersion = 0;\n return [querySet, undefined];\n }\n this.outstandingAuthOlderThanRestart = true;\n const authenticate: Authenticate = {\n type: \"Authenticate\",\n baseVersion: 0,\n ...this.auth,\n };\n this.identityVersion = 1;\n return [querySet, authenticate];\n }\n\n pause() {\n this.paused = true;\n }\n\n resume(): [QuerySetModification | undefined, Authenticate | undefined] {\n const querySet: QuerySetModification | undefined =\n this.pendingQuerySetModifications.size > 0\n ? {\n type: \"ModifyQuerySet\",\n baseVersion: this.querySetVersion,\n newVersion: ++this.querySetVersion,\n modifications: Array.from(\n this.pendingQuerySetModifications.values(),\n ),\n }\n : undefined;\n const authenticate: Authenticate | undefined =\n this.auth !== undefined\n ? {\n type: \"Authenticate\",\n baseVersion: this.identityVersion++,\n ...this.auth,\n }\n : undefined;\n\n this.unpause();\n\n return [querySet, authenticate];\n }\n\n private unpause() {\n this.paused = false;\n this.pendingQuerySetModifications.clear();\n }\n\n private removeSubscriber(\n queryToken: QueryToken,\n ): QuerySetModification | null {\n const localQuery = this.querySet.get(queryToken)!;\n\n if (localQuery.numSubscribers > 1) {\n localQuery.numSubscribers -= 1;\n return null;\n } else {\n this.querySet.delete(queryToken);\n this.queryIdToToken.delete(localQuery.id);\n this.outstandingQueriesOlderThanRestart.delete(localQuery.id);\n const baseVersion = this.querySetVersion;\n const newVersion = this.querySetVersion + 1;\n const remove: RemoveQuery = {\n type: \"Remove\",\n queryId: localQuery.id,\n };\n if (this.paused) {\n if (this.pendingQuerySetModifications.has(localQuery.id)) {\n this.pendingQuerySetModifications.delete(localQuery.id);\n } else {\n this.pendingQuerySetModifications.set(localQuery.id, remove);\n }\n } else {\n this.querySetVersion = newVersion;\n }\n return {\n type: \"ModifyQuerySet\",\n baseVersion,\n newVersion,\n modifications: [remove],\n };\n }\n }\n}\n", "import { jsonToConvex } from \"../../values/index.js\";\nimport { logForFunction, Logger } from \"../logging.js\";\nimport { Long } from \"../../vendor/long.js\";\nimport { FunctionResult } from \"./function_result.js\";\nimport {\n ActionRequest,\n ActionResponse,\n ClientMessage,\n MutationRequest,\n MutationResponse,\n RequestId,\n} from \"./protocol.js\";\n\ntype RequestStatus =\n | {\n status: \"Requested\" | \"NotSent\";\n onResult: (result: FunctionResult) => void;\n requestedAt: Date;\n }\n | {\n status: \"Completed\";\n result: FunctionResult;\n onResolve: () => void;\n ts: Long;\n };\n\nexport class RequestManager {\n private inflightRequests: Map<\n RequestId,\n {\n message: MutationRequest | ActionRequest;\n status: RequestStatus;\n }\n >;\n private requestsOlderThanRestart: Set<RequestId>;\n private inflightMutationsCount: number = 0;\n private inflightActionsCount: number = 0;\n constructor(\n private readonly logger: Logger,\n private readonly markConnectionStateDirty: () => void,\n ) {\n this.inflightRequests = new Map();\n this.requestsOlderThanRestart = new Set();\n }\n\n request(\n message: MutationRequest | ActionRequest,\n sent: boolean,\n ): Promise<FunctionResult> {\n const result = new Promise<FunctionResult>((resolve) => {\n const status = sent ? \"Requested\" : \"NotSent\";\n this.inflightRequests.set(message.requestId, {\n message,\n status: { status, requestedAt: new Date(), onResult: resolve },\n });\n\n if (message.type === \"Mutation\") {\n this.inflightMutationsCount++;\n } else if (message.type === \"Action\") {\n this.inflightActionsCount++;\n }\n });\n\n this.markConnectionStateDirty();\n return result;\n }\n\n /**\n * Update the state after receiving a response.\n *\n * @returns A RequestId if the request is complete and its optimistic update\n * can be dropped, null otherwise.\n */\n onResponse(\n response: MutationResponse | ActionResponse,\n ): { requestId: RequestId; result: FunctionResult } | null {\n const requestInfo = this.inflightRequests.get(response.requestId);\n if (requestInfo === undefined) {\n // Annoyingly we can occasionally get responses to mutations that we're no\n // longer tracking. One flow where this happens is:\n // 1. Client sends mutation 1\n // 2. Client gets response for mutation 1. The sever says that it was committed at ts=10.\n // 3. Client is disconnected\n // 4. Client reconnects and re-issues queries and this mutation.\n // 5. Server sends transition message to ts=20\n // 6. Client drops mutation because it's already been observed.\n // 7. Client receives a second response for mutation 1 but doesn't know about it anymore.\n\n // The right fix for this is probably to add a reconciliation phase on\n // reconnection where we receive responses to all the mutations before\n // the transition message so this flow could never happen (CX-1513).\n\n // For now though, we can just ignore this message.\n return null;\n }\n\n // Because `.restart()` re-requests completed requests, we may get some\n // responses for requests that are already in the \"Completed\" state.\n // We can safely ignore those because we've already notified the UI about\n // their results.\n if (requestInfo.status.status === \"Completed\") {\n return null;\n }\n\n const udfType =\n requestInfo.message.type === \"Mutation\" ? \"mutation\" : \"action\";\n const udfPath = requestInfo.message.udfPath;\n\n for (const line of response.logLines) {\n logForFunction(this.logger, \"info\", udfType, udfPath, line);\n }\n\n const status = requestInfo.status;\n let result: FunctionResult;\n let onResolve;\n if (response.success) {\n result = {\n success: true,\n logLines: response.logLines,\n value: jsonToConvex(response.result),\n };\n onResolve = () => status.onResult(result);\n } else {\n const errorMessage = response.result as string;\n const { errorData } = response;\n logForFunction(this.logger, \"error\", udfType, udfPath, errorMessage);\n result = {\n success: false,\n errorMessage,\n errorData:\n errorData !== undefined ? jsonToConvex(errorData) : undefined,\n logLines: response.logLines,\n };\n onResolve = () => status.onResult(result);\n }\n\n // We can resolve Mutation failures immediately since they don't have any\n // side effects. Actions are intentionally decoupled from\n // queries/mutations here on the sync protocol since they have different\n // guarantees.\n if (response.type === \"ActionResponse\" || !response.success) {\n onResolve();\n this.inflightRequests.delete(response.requestId);\n this.requestsOlderThanRestart.delete(response.requestId);\n\n if (requestInfo.message.type === \"Action\") {\n this.inflightActionsCount--;\n } else if (requestInfo.message.type === \"Mutation\") {\n this.inflightMutationsCount--;\n }\n\n this.markConnectionStateDirty();\n return { requestId: response.requestId, result };\n }\n\n // We have to wait to resolve the request promise until after we transition\n // past this timestamp so clients can read their own writes.\n requestInfo.status = {\n status: \"Completed\",\n result,\n ts: response.ts,\n onResolve,\n };\n\n return null;\n }\n\n // Remove and returns completed requests.\n removeCompleted(ts: Long): Map<RequestId, FunctionResult> {\n const completeRequests: Map<RequestId, FunctionResult> = new Map();\n for (const [requestId, requestInfo] of this.inflightRequests.entries()) {\n const status = requestInfo.status;\n if (status.status === \"Completed\" && status.ts.lessThanOrEqual(ts)) {\n status.onResolve();\n completeRequests.set(requestId, status.result);\n\n if (requestInfo.message.type === \"Mutation\") {\n this.inflightMutationsCount--;\n } else if (requestInfo.message.type === \"Action\") {\n this.inflightActionsCount--;\n }\n\n this.inflightRequests.delete(requestId);\n this.requestsOlderThanRestart.delete(requestId);\n }\n }\n if (completeRequests.size > 0) {\n this.markConnectionStateDirty();\n }\n return completeRequests;\n }\n\n restart(): ClientMessage[] {\n // When we reconnect to the backend, re-request all requests that are safe\n // to be resend.\n\n this.requestsOlderThanRestart = new Set(this.inflightRequests.keys());\n const allMessages = [];\n for (const [requestId, value] of this.inflightRequests) {\n if (value.status.status === \"NotSent\") {\n value.status.status = \"Requested\";\n allMessages.push(value.message);\n continue;\n }\n\n if (value.message.type === \"Mutation\") {\n // This includes ones that have already been completed because we still\n // want to tell the backend to transition the client past the completed\n // timestamp. This is safe since mutations are idempotent.\n allMessages.push(value.message);\n } else if (value.message.type === \"Action\") {\n // Unlike mutations, actions are not idempotent. When we reconnect to the\n // backend, we don't know if it is safe to resend in-flight actions, so we\n // cancel them and consider them failed.\n this.inflightRequests.delete(requestId);\n this.requestsOlderThanRestart.delete(requestId);\n this.inflightActionsCount--;\n if (value.status.status === \"Completed\") {\n throw new Error(\"Action should never be in 'Completed' state\");\n }\n value.status.onResult({\n success: false,\n errorMessage: \"Connection lost while action was in flight\",\n logLines: [],\n });\n }\n }\n this.markConnectionStateDirty();\n return allMessages;\n }\n\n resume(): ClientMessage[] {\n const allMessages = [];\n for (const [, value] of this.inflightRequests) {\n if (value.status.status === \"NotSent\") {\n value.status.status = \"Requested\";\n allMessages.push(value.message);\n continue;\n }\n }\n return allMessages;\n }\n\n /**\n * @returns true if there are any requests that have been requested but have\n * not be completed yet.\n */\n hasIncompleteRequests(): boolean {\n for (const requestInfo of this.inflightRequests.values()) {\n if (requestInfo.status.status === \"Requested\") {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @returns true if there are any inflight requests, including ones that have\n * completed on the server, but have not been applied.\n */\n hasInflightRequests(): boolean {\n return this.inflightRequests.size > 0;\n }\n\n /**\n * @returns true if there are any inflight requests, that have been hanging around\n * since prior to the most recent restart.\n */\n hasSyncedPastLastReconnect(): boolean {\n return this.requestsOlderThanRestart.size === 0;\n }\n\n timeOfOldestInflightRequest(): Date | null {\n if (this.inflightRequests.size === 0) {\n return null;\n }\n let oldestInflightRequest = Date.now();\n for (const request of this.inflightRequests.values()) {\n if (request.status.status !== \"Completed\") {\n if (request.status.requestedAt.getTime() < oldestInflightRequest) {\n oldestInflightRequest = request.status.requestedAt.getTime();\n }\n }\n }\n return new Date(oldestInflightRequest);\n }\n\n /**\n * @returns The number of mutations currently in flight.\n */\n inflightMutations(): number {\n return this.inflightMutationsCount;\n }\n\n /**\n * @returns The number of actions currently in flight.\n */\n inflightActions(): number {\n return this.inflightActionsCount;\n }\n}\n", "/**\n * A symbol for accessing the name of a {@link FunctionReference} at runtime.\n */\nexport const functionName = Symbol.for(\"functionName\");\n", "import { functionName } from \"../functionName.js\";\n\nexport const toReferencePath = Symbol.for(\"toReferencePath\");\n\n// Multiple instances of the same Symbol.for() are equal at runtime but not\n// at type-time, so `[toReferencePath]` properties aren't used in types.\n// Use this function to set the property invisibly.\nexport function setReferencePath<T>(obj: T, value: string) {\n (obj as any)[toReferencePath] = value;\n}\n\nexport function extractReferencePath(reference: any): string | null {\n return reference[toReferencePath] ?? null;\n}\n\nexport function isFunctionHandle(s: string): boolean {\n return s.startsWith(\"function://\");\n}\n\nexport function getFunctionAddress(functionReference: any) {\n // The `run*` syscalls expect either a UDF path at \"name\" or a serialized\n // reference at \"reference\". Dispatch on `functionReference` to coerce\n // it to one or the other.\n let functionAddress;\n\n // Legacy path for passing in UDF paths directly as function references.\n if (typeof functionReference === \"string\") {\n if (isFunctionHandle(functionReference)) {\n functionAddress = { functionHandle: functionReference };\n } else {\n functionAddress = { name: functionReference };\n }\n }\n // Path for passing in a `FunctionReference`, either from `api` or directly\n // created from a UDF path with `makeFunctionReference`.\n else if (functionReference[functionName]) {\n functionAddress = { name: functionReference[functionName] };\n }\n // Reference to a component's function derived from `app` or `component`.\n else {\n const referencePath = extractReferencePath(functionReference);\n if (!referencePath) {\n throw new Error(`${functionReference} is not a functionReference`);\n }\n functionAddress = { reference: referencePath };\n }\n return functionAddress;\n}\n", "import {\n EmptyObject,\n DefaultFunctionArgs,\n FunctionVisibility,\n RegisteredAction,\n RegisteredMutation,\n RegisteredQuery,\n} from \"./registration.js\";\nimport { Expand, UnionToIntersection } from \"../type_utils.js\";\nimport { PaginationOptions, PaginationResult } from \"./pagination.js\";\nimport { functionName } from \"./functionName.js\";\nimport { getFunctionAddress } from \"./components/paths.js\";\n\n/**\n * The type of a Convex function.\n *\n * @public\n */\nexport type FunctionType = \"query\" | \"mutation\" | \"action\";\n\n/**\n * A reference to a registered Convex function.\n *\n * You can create a {@link FunctionReference} using the generated `api` utility:\n * ```js\n * import { api } from \"../convex/_generated/api\";\n *\n * const reference = api.myModule.myFunction;\n * ```\n *\n * If you aren't using code generation, you can create references using\n * {@link anyApi}:\n * ```js\n * import { anyApi } from \"convex/server\";\n *\n * const reference = anyApi.myModule.myFunction;\n * ```\n *\n * Function references can be used to invoke functions from the client. For\n * example, in React you can pass references to the {@link react.useQuery} hook:\n * ```js\n * const result = useQuery({\n * query: api.myModule.myFunction,\n * args: {},\n * throwOnError: true,\n * }).data;\n * ```\n *\n * @typeParam Type - The type of the function (\"query\", \"mutation\", or \"action\").\n * @typeParam Visibility - The visibility of the function (\"public\" or \"internal\").\n * @typeParam Args - The arguments to this function. This is an object mapping\n * argument names to their types.\n * @typeParam ReturnType - The return type of this function.\n * @public\n */\nexport type FunctionReference<\n Type extends FunctionType,\n Visibility extends FunctionVisibility = \"public\",\n Args extends DefaultFunctionArgs = any,\n ReturnType = any,\n ComponentPath = string | undefined,\n> = {\n _type: Type;\n _visibility: Visibility;\n _args: Args;\n _returnType: ReturnType;\n _componentPath: ComponentPath;\n};\n\n/**\n * Get the name of a function from a {@link FunctionReference}.\n *\n * The name is a string like \"myDir/myModule:myFunction\". If the exported name\n * of the function is `\"default\"`, the function name is omitted\n * (e.g. \"myDir/myModule\").\n *\n * @param functionReference - A {@link FunctionReference} to get the name of.\n * @returns A string of the function's name.\n *\n * @public\n */\nexport function getFunctionName(\n functionReference: AnyFunctionReference,\n): string {\n const address = getFunctionAddress(functionReference);\n\n if (address.name === undefined) {\n if (address.functionHandle !== undefined) {\n throw new Error(\n `Expected function reference like \"api.file.func\" or \"internal.file.func\", but received function handle ${address.functionHandle}`,\n );\n } else if (address.reference !== undefined) {\n throw new Error(\n `Expected function reference in the current component like \"api.file.func\" or \"internal.file.func\", but received reference ${address.reference}`,\n );\n }\n throw new Error(\n `Expected function reference like \"api.file.func\" or \"internal.file.func\", but received ${JSON.stringify(address)}`,\n );\n }\n // Both a legacy thing and also a convenience for interactive use:\n // the types won't check but a string is always allowed at runtime.\n if (typeof functionReference === \"string\") return functionReference;\n\n // Two different runtime values for FunctionReference implement this\n // interface: api objects returned from `createApi()` and standalone\n // function reference objects returned from makeFunctionReference.\n const name = (functionReference as any)[functionName];\n if (!name) {\n throw new Error(`${functionReference as any} is not a functionReference`);\n }\n return name;\n}\n\n/**\n * FunctionReferences generally come from generated code, but in custom clients\n * it may be useful to be able to build one manually.\n *\n * Real function references are empty objects at runtime, but the same interface\n * can be implemented with an object for tests and clients which don't use\n * code generation.\n *\n * @param name - The identifier of the function. E.g. `path/to/file:functionName`\n * @public\n */\nexport function makeFunctionReference<\n type extends FunctionType,\n args extends DefaultFunctionArgs = any,\n ret = any,\n>(name: string): FunctionReference<type, \"public\", args, ret> {\n return { [functionName]: name } as unknown as FunctionReference<\n type,\n \"public\",\n args,\n ret\n >;\n}\n\n/**\n * Create a runtime API object that implements {@link AnyApi}.\n *\n * This allows accessing any path regardless of what directories, modules,\n * or functions are defined.\n *\n * @param pathParts - The path to the current node in the API.\n * @returns An {@link AnyApi}\n * @public\n */\nfunction createApi(pathParts: string[] = []): AnyApi {\n const handler: ProxyHandler<object> = {\n get(_, prop: string | symbol) {\n if (typeof prop === \"string\") {\n const newParts = [...pathParts, prop];\n return createApi(newParts);\n } else if (prop === functionName) {\n if (pathParts.length < 2) {\n const found = [\"api\", ...pathParts].join(\".\");\n throw new Error(\n `API path is expected to be of the form \\`api.moduleName.functionName\\`. Found: \\`${found}\\``,\n );\n }\n const path = pathParts.slice(0, -1).join(\"/\");\n const exportName = pathParts[pathParts.length - 1];\n if (exportName === \"default\") {\n return path;\n } else {\n return path + \":\" + exportName;\n }\n } else if (prop === Symbol.toStringTag) {\n return \"FunctionReference\";\n } else {\n return undefined;\n }\n },\n };\n\n return new Proxy({}, handler);\n}\n\n/**\n * Given an export from a module, convert it to a {@link FunctionReference}\n * if it is a Convex function.\n */\nexport type FunctionReferenceFromExport<Export> =\n Export extends RegisteredQuery<\n infer Visibility,\n infer Args,\n infer ReturnValue\n >\n ? FunctionReference<\n \"query\",\n Visibility,\n Args,\n ConvertReturnType<ReturnValue>\n >\n : Export extends RegisteredMutation<\n infer Visibility,\n infer Args,\n infer ReturnValue\n >\n ? FunctionReference<\n \"mutation\",\n Visibility,\n Args,\n ConvertReturnType<ReturnValue>\n >\n : Export extends RegisteredAction<\n infer Visibility,\n infer Args,\n infer ReturnValue\n >\n ? FunctionReference<\n \"action\",\n Visibility,\n Args,\n ConvertReturnType<ReturnValue>\n >\n : never;\n\n/**\n * Given a module, convert all the Convex functions into\n * {@link FunctionReference}s and remove the other exports.\n *\n * BE CAREFUL WHEN EDITING THIS!\n *\n * This is written carefully to preserve jumping to function definitions using\n * cmd+click. If you edit it, please test that cmd+click still works.\n */\ntype FunctionReferencesInModule<Module extends Record<string, any>> = {\n -readonly [ExportName in keyof Module as Module[ExportName][\"isConvexFunction\"] extends true\n ? ExportName\n : never]: FunctionReferenceFromExport<Module[ExportName]>;\n};\n\n/**\n * Given a path to a module and it's type, generate an API type for this module.\n *\n * This is a nested object according to the module's path.\n */\ntype ApiForModule<\n ModulePath extends string,\n Module extends object,\n> = ModulePath extends `${infer First}/${infer Second}`\n ? {\n [_ in First]: ApiForModule<Second, Module>;\n }\n : { [_ in ModulePath]: FunctionReferencesInModule<Module> };\n\n/**\n * Given the types of all modules in the `convex/` directory, construct the type\n * of `api`.\n *\n * `api` is a utility for constructing {@link FunctionReference}s.\n *\n * @typeParam AllModules - A type mapping module paths (like `\"dir/myModule\"`) to\n * the types of the modules.\n * @public\n */\nexport type ApiFromModules<AllModules extends Record<string, object>> =\n FilterApi<\n ApiFromModulesAllowEmptyNodes<AllModules>,\n FunctionReference<any, any, any, any>\n >;\n\ntype ApiFromModulesAllowEmptyNodes<AllModules extends Record<string, object>> =\n ExpandModulesAndDirs<\n UnionToIntersection<\n {\n [ModulePath in keyof AllModules]: ApiForModule<\n ModulePath & string,\n AllModules[ModulePath]\n >;\n }[keyof AllModules]\n >\n >;\n\ntype FilterKeysInApi<key, API, Predicate> = API extends Predicate\n ? key\n : API extends FunctionReference<any, any, any, any>\n ? never\n : FilterApi<API, Predicate> extends Record<string, never>\n ? never\n : key;\n\n/**\n * @public\n *\n * Filter a Convex deployment api object for functions which meet criteria,\n * for example all public queries.\n */\nexport type FilterApi<API, Predicate> = Expand<{\n [mod in keyof API as FilterKeysInApi<\n mod,\n API[mod],\n Predicate\n >]: API[mod] extends Predicate ? API[mod] : FilterApi<API[mod], Predicate>;\n}>;\n\n/**\n * Given an api of type API and a FunctionReference subtype, return an api object\n * containing only the function references that match.\n *\n * ```ts\n * const q = filterApi<typeof api, FunctionReference<\"query\">>(api)\n * ```\n *\n * @public\n */\nexport function filterApi<API, Predicate>(api: API): FilterApi<API, Predicate> {\n return api as any;\n}\n\n// These just* API filter helpers require no type parameters so are useable from JavaScript.\n/** @public */\nexport function justInternal<API>(\n api: API,\n): FilterApi<API, FunctionReference<any, \"internal\", any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justPublic<API>(\n api: API,\n): FilterApi<API, FunctionReference<any, \"public\", any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justQueries<API>(\n api: API,\n): FilterApi<API, FunctionReference<\"query\", any, any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justMutations<API>(\n api: API,\n): FilterApi<API, FunctionReference<\"mutation\", any, any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justActions<API>(\n api: API,\n): FilterApi<API, FunctionReference<\"action\", any, any, any>> {\n return api as any;\n}\n\n/** @public */\nexport function justPaginatedQueries<API>(\n api: API,\n): FilterApi<\n API,\n FunctionReference<\n \"query\",\n any,\n { paginationOpts: PaginationOptions },\n PaginationResult<any>\n >\n> {\n return api as any;\n}\n\n/** @public */\nexport function justSchedulable<API>(\n api: API,\n): FilterApi<API, FunctionReference<\"mutation\" | \"action\", any, any, any>> {\n return api as any;\n}\n\n/**\n * Like {@link Expand}, this simplifies how TypeScript displays object types.\n * The differences are:\n * 1. This version is recursive.\n * 2. This stops recursing when it hits a {@link FunctionReference}.\n */\ntype ExpandModulesAndDirs<ObjectType> = ObjectType extends AnyFunctionReference\n ? ObjectType\n : {\n [Key in keyof ObjectType]: ExpandModulesAndDirs<ObjectType[Key]>;\n };\n\n/**\n * A {@link FunctionReference} of any type and any visibility with any\n * arguments and any return type.\n *\n * @public\n */\nexport type AnyFunctionReference = FunctionReference<any, any>;\n\ntype AnyModuleDirOrFunc = {\n [key: string]: AnyModuleDirOrFunc;\n} & AnyFunctionReference;\n\n/**\n * The type that Convex api objects extend. If you were writing an api from\n * scratch it should extend this type.\n *\n * @public\n */\nexport type AnyApi = Record<string, Record<string, AnyModuleDirOrFunc>>;\n\n/**\n * Recursive partial API, useful for defining a subset of an API when mocking\n * or building custom api objects.\n *\n * @public\n */\nexport type PartialApi<API> = {\n [mod in keyof API]?: API[mod] extends FunctionReference<any, any, any, any>\n ? API[mod]\n : PartialApi<API[mod]>;\n};\n\n/**\n * A utility for constructing {@link FunctionReference}s in projects that\n * are not using code generation.\n *\n * You can create a reference to a function like:\n * ```js\n * const reference = anyApi.myModule.myFunction;\n * ```\n *\n * This supports accessing any path regardless of what directories and modules\n * are in your project. All function references are typed as\n * {@link AnyFunctionReference}.\n *\n *\n * If you're using code generation, use `api` from `convex/_generated/api`\n * instead. It will be more type-safe and produce better auto-complete\n * in your editor.\n *\n * @public\n */\nexport const anyApi: AnyApi = createApi() as any;\n\n/**\n * Given a {@link FunctionReference}, get the return type of the function.\n *\n * This is represented as an object mapping argument names to values.\n * @public\n */\nexport type FunctionArgs<FuncRef extends AnyFunctionReference> =\n FuncRef[\"_args\"];\n\n/**\n * A tuple type of the (maybe optional) arguments to `FuncRef`.\n *\n * This type is used to make methods involving arguments type safe while allowing\n * skipping the arguments for functions that don't require arguments.\n *\n * @public\n */\nexport type OptionalRestArgs<FuncRef extends AnyFunctionReference> =\n FuncRef[\"_args\"] extends EmptyObject\n ? [args?: EmptyObject]\n : [args: FuncRef[\"_args\"]];\n\n/**\n * A tuple type of the (maybe optional) arguments to `FuncRef`, followed by an options\n * object of type `Options`.\n *\n * This type is used to make methods like `useQuery` type-safe while allowing\n * 1. Skipping arguments for functions that don't require arguments.\n * 2. Skipping the options object.\n * @public\n */\nexport type ArgsAndOptions<\n FuncRef extends AnyFunctionReference,\n Options,\n> = FuncRef[\"_args\"] extends EmptyObject\n ? [args?: EmptyObject, options?: Options]\n : [args: FuncRef[\"_args\"], options?: Options];\n\n/**\n * Given a {@link FunctionReference}, get the return type of the function.\n *\n * @public\n */\nexport type FunctionReturnType<FuncRef extends AnyFunctionReference> =\n FuncRef[\"_returnType\"];\n\ntype UndefinedToNull<T> = T extends void ? null : T;\n\ntype NullToUndefinedOrNull<T> = T extends null ? T | undefined | void : T;\n\n/**\n * Convert the return type of a function to it's client-facing format.\n *\n * This means:\n * - Converting `undefined` and `void` to `null`\n * - Removing all `Promise` wrappers\n */\nexport type ConvertReturnType<T> = UndefinedToNull<Awaited<T>>;\n\nexport type ValidatorTypeToReturnType<T> =\n | Promise<NullToUndefinedOrNull<T>>\n | NullToUndefinedOrNull<T>;\n", "import {\n FunctionArgs,\n FunctionReference,\n FunctionReturnType,\n OptionalRestArgs,\n getFunctionName,\n} from \"../../server/api.js\";\nimport { parseArgs } from \"../../common/index.js\";\nimport { Value } from \"../../values/index.js\";\nimport { createHybridErrorStacktrace, forwardData } from \"../logging.js\";\nimport { FunctionResult } from \"./function_result.js\";\nimport { OptimisticLocalStore } from \"./optimistic_updates.js\";\nimport { RequestId } from \"./protocol.js\";\nimport {\n canonicalizeUdfPath,\n QueryToken,\n serializePathAndArgs,\n} from \"./udf_path_utils.js\";\nimport { ConvexError } from \"../../values/errors.js\";\n\n/**\n * An optimistic update function that has been curried over its arguments.\n */\ntype WrappedOptimisticUpdate = (locaQueryStore: OptimisticLocalStore) => void;\n\n/**\n * The implementation of `OptimisticLocalStore`.\n *\n * This class provides the interface for optimistic updates to modify query results.\n */\nclass OptimisticLocalStoreImpl implements OptimisticLocalStore {\n // A references of the query results in OptimisticQueryResults\n private readonly queryResults: QueryResultsMap;\n\n // All of the queries modified by this class\n readonly modifiedQueries: QueryToken[];\n\n constructor(queryResults: QueryResultsMap) {\n this.queryResults = queryResults;\n this.modifiedQueries = [];\n }\n\n getQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgs<Query>\n ): undefined | FunctionReturnType<Query> {\n const queryArgs = parseArgs(args[0]);\n const name = getFunctionName(query);\n const queryResult = this.queryResults.get(\n serializePathAndArgs(name, queryArgs),\n );\n if (queryResult === undefined) {\n return undefined;\n }\n return OptimisticLocalStoreImpl.queryValue(queryResult.result);\n }\n\n getAllQueries<Query extends FunctionReference<\"query\">>(\n query: Query,\n ): {\n args: FunctionArgs<Query>;\n value: undefined | FunctionReturnType<Query>;\n }[] {\n const queriesWithName: {\n args: FunctionArgs<Query>;\n value: undefined | FunctionReturnType<Query>;\n }[] = [];\n const name = getFunctionName(query);\n for (const queryResult of this.queryResults.values()) {\n if (queryResult.udfPath === canonicalizeUdfPath(name)) {\n queriesWithName.push({\n args: queryResult.args as FunctionArgs<Query>,\n value: OptimisticLocalStoreImpl.queryValue(queryResult.result),\n });\n }\n }\n return queriesWithName;\n }\n\n setQuery<QueryReference extends FunctionReference<\"query\">>(\n queryReference: QueryReference,\n args: FunctionArgs<QueryReference>,\n value: undefined | FunctionReturnType<QueryReference>,\n ): void {\n const queryArgs = parseArgs(args);\n const name = getFunctionName(queryReference);\n const queryToken = serializePathAndArgs(name, queryArgs);\n\n let result: FunctionResult | undefined;\n if (value === undefined) {\n result = undefined;\n } else {\n result = {\n success: true,\n value,\n // It's an optimistic update, so there are no function logs to show.\n logLines: [],\n };\n }\n const query: Query = {\n udfPath: name,\n args: queryArgs,\n result,\n };\n this.queryResults.set(queryToken, query);\n this.modifiedQueries.push(queryToken);\n }\n\n private static queryValue(\n result: FunctionResult | undefined,\n ): Value | undefined {\n if (result === undefined) {\n return undefined;\n } else if (result.success) {\n return result.value;\n } else {\n // If the query is an error state, just return `undefined` as though\n // it's loading. Optimistic updates should already handle `undefined` well\n // and there isn't a need to break the whole update because it tried\n // to load a single query that errored.\n return undefined;\n }\n }\n}\n\ntype OptimisticUpdateAndId = {\n update: WrappedOptimisticUpdate;\n mutationId: RequestId;\n};\n\ntype Query = {\n // undefined means the query was set to be loading (undefined) in an optimistic update.\n // Note that we can also have queries not present in the QueryResultMap\n // at all because they are still loading from the server and have no optimistic update\n // setting an optimistic value in advance.\n result: FunctionResult | undefined;\n udfPath: string;\n args: Record<string, Value>;\n};\nexport type QueryResultsMap = Map<QueryToken, Query>;\n\ntype ChangedQueries = QueryToken[];\n\n/**\n * A view of all of our query results with optimistic updates applied on top.\n */\nexport class OptimisticQueryResults {\n private queryResults: QueryResultsMap;\n private optimisticUpdates: OptimisticUpdateAndId[];\n\n constructor() {\n this.queryResults = new Map();\n this.optimisticUpdates = [];\n }\n\n /**\n * Apply all optimistic updates on top of server query results\n */\n ingestQueryResultsFromServer(\n serverQueryResults: QueryResultsMap,\n optimisticUpdatesToDrop: Set<RequestId>,\n ): ChangedQueries {\n this.optimisticUpdates = this.optimisticUpdates.filter((updateAndId) => {\n return !optimisticUpdatesToDrop.has(updateAndId.mutationId);\n });\n\n const oldQueryResults = this.queryResults;\n this.queryResults = new Map(serverQueryResults);\n const localStore = new OptimisticLocalStoreImpl(this.queryResults);\n for (const updateAndId of this.optimisticUpdates) {\n updateAndId.update(localStore);\n }\n\n // To find the changed queries, just do a shallow comparison\n // TODO(CX-733): Change this so we avoid unnecessary rerenders\n const changedQueries: ChangedQueries = [];\n for (const [queryToken, query] of this.queryResults) {\n const oldQuery = oldQueryResults.get(queryToken);\n if (oldQuery === undefined || oldQuery.result !== query.result) {\n changedQueries.push(queryToken);\n }\n }\n\n return changedQueries;\n }\n\n applyOptimisticUpdate(\n update: WrappedOptimisticUpdate,\n mutationId: RequestId,\n ): ChangedQueries {\n // Apply the update to our store\n this.optimisticUpdates.push({\n update,\n mutationId,\n });\n const localStore = new OptimisticLocalStoreImpl(this.queryResults);\n update(localStore);\n\n // Notify about any query results that changed\n // TODO(CX-733): Change this so we avoid unnecessary rerenders\n return localStore.modifiedQueries;\n }\n\n /**\n * \"Raw\" with respect to errors vs values, but query results still have\n * optimistic updates applied.\n *\n * @internal\n */\n rawQueryResult(queryToken: QueryToken): FunctionResult | undefined {\n const query = this.queryResults.get(queryToken);\n if (query === undefined) {\n return undefined;\n }\n return query.result;\n }\n\n queryResult(queryToken: QueryToken): Value | undefined {\n const query = this.queryResults.get(queryToken);\n if (query === undefined) {\n return undefined;\n }\n const result = query.result;\n if (result === undefined) {\n return undefined;\n } else if (result.success) {\n return result.value;\n } else {\n if (result.errorData !== undefined) {\n throw forwardData(\n result,\n new ConvexError(\n createHybridErrorStacktrace(\"query\", query.udfPath, result),\n ),\n );\n }\n throw new Error(\n createHybridErrorStacktrace(\"query\", query.udfPath, result),\n );\n }\n }\n\n hasQueryResult(queryToken: QueryToken): boolean {\n return this.queryResults.get(queryToken) !== undefined;\n }\n\n /**\n * @internal\n */\n queryLogs(queryToken: QueryToken): string[] | undefined {\n const query = this.queryResults.get(queryToken);\n return query?.result?.logLines;\n }\n}\n", "// Implements an unsigned long.\n// This is a subset of https://github.com/dcodeIO/Long.js,\n// vendored to decrease bundle size.\n// Copyright Daniel Wirtz <dcode@dcode.io>\n// License: Apache Version 2.0\n/*\n\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright 2023 Daniel Wirtz <dcode@dcode.io>\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\n// This works... but don't try to compare one to a real Long.js Long!\n// For internal use only.\n// `| 0` assures the runtime that we are using integer arithmetic\nexport class Long {\n low: number;\n high: number;\n __isUnsignedLong__: boolean;\n\n static isLong(obj: Long) {\n return (obj && obj.__isUnsignedLong__) === true;\n }\n\n constructor(low: number, high: number) {\n this.low = low | 0;\n this.high = high | 0;\n this.__isUnsignedLong__ = true;\n }\n\n // prettier-ignore\n static fromBytesLE(bytes: number[]): Long {\n return new Long(\n bytes[0] |\n bytes[1] << 8 |\n bytes[2] << 16 |\n bytes[3] << 24,\n bytes[4] |\n bytes[5] << 8 |\n bytes[6] << 16 |\n bytes[7] << 24,\n );\n }\n\n // prettier-ignore\n toBytesLE() {\n const hi = this.high;\n const lo = this.low;\n return [\n lo & 0xff,\n lo >>> 8 & 0xff,\n lo >>> 16 & 0xff,\n lo >>> 24,\n hi & 0xff,\n hi >>> 8 & 0xff,\n hi >>> 16 & 0xff,\n hi >>> 24\n ];\n }\n\n static fromNumber(value: number) {\n if (isNaN(value)) return UZERO;\n if (value < 0) return UZERO;\n if (value >= TWO_PWR_64_DBL) return MAX_UNSIGNED_VALUE;\n return new Long(value % TWO_PWR_32_DBL | 0, (value / TWO_PWR_32_DBL) | 0);\n }\n\n toString() {\n return (\n BigInt(this.high) * BigInt(TWO_PWR_32_DBL) +\n BigInt(this.low)\n ).toString();\n }\n\n equals(other: Long) {\n if (!Long.isLong(other)) other = Long.fromValue(other);\n if (this.high >>> 31 === 1 && other.high >>> 31 === 1) return false;\n return this.high === other.high && this.low === other.low;\n }\n\n notEquals(other: Long) {\n return !this.equals(other);\n }\n\n comp(other: Long) {\n if (!Long.isLong(other)) other = Long.fromValue(other);\n if (this.equals(other)) return 0;\n return other.high >>> 0 > this.high >>> 0 ||\n (other.high === this.high && other.low >>> 0 > this.low >>> 0)\n ? -1\n : 1;\n }\n\n lessThanOrEqual(other: Long) {\n return this.comp(/* validates */ other) <= 0;\n }\n\n static fromValue(val: any) {\n if (typeof val === \"number\") return Long.fromNumber(val);\n // Throws for non-objects, converts non-instanceof Long:\n return new Long(val.low, val.high);\n }\n}\n\nconst UZERO = new Long(0, 0);\nconst TWO_PWR_16_DBL = 1 << 16;\nconst TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;\nconst TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;\nconst MAX_UNSIGNED_VALUE = new Long(0xffffffff | 0, 0xffffffff | 0);\n", "import { jsonToConvex } from \"../../values/index.js\";\nimport { Long } from \"../../vendor/long.js\";\nimport { logForFunction, Logger } from \"../logging.js\";\nimport { QueryId, StateVersion, Transition } from \"./protocol.js\";\nimport { FunctionResult } from \"./function_result.js\";\n\n/**\n * A represention of the query results we've received on the current WebSocket\n * connection.\n *\n * Queries you won't find here include:\n * - queries which have been requested, but no query transition has been received yet for\n * - queries which are populated only though active optimistic updates, but are not subscribed to\n * - queries which have already been removed by the server (which it shouldn't do unless that's\n * been requested by the client)\n */\nexport class RemoteQuerySet {\n private version: StateVersion;\n private readonly remoteQuerySet: Map<QueryId, FunctionResult>;\n private readonly queryPath: (queryId: QueryId) => string | null;\n private readonly logger: Logger;\n\n constructor(queryPath: (queryId: QueryId) => string | null, logger: Logger) {\n this.version = { querySet: 0, ts: Long.fromNumber(0), identity: 0 };\n this.remoteQuerySet = new Map();\n this.queryPath = queryPath;\n this.logger = logger;\n }\n\n transition(transition: Transition): void {\n const start = transition.startVersion;\n if (\n this.version.querySet !== start.querySet ||\n this.version.ts.notEquals(start.ts) ||\n this.version.identity !== start.identity\n ) {\n throw new Error(\n `Invalid start version: ${start.ts.toString()}:${start.querySet}:${start.identity}, transitioning from ${this.version.ts.toString()}:${this.version.querySet}:${this.version.identity}`,\n );\n }\n for (const modification of transition.modifications) {\n switch (modification.type) {\n case \"QueryUpdated\": {\n const queryPath = this.queryPath(modification.queryId);\n if (queryPath) {\n for (const line of modification.logLines) {\n logForFunction(this.logger, \"info\", \"query\", queryPath, line);\n }\n }\n const value = jsonToConvex(modification.value ?? null);\n this.remoteQuerySet.set(modification.queryId, {\n success: true,\n value,\n logLines: modification.logLines,\n });\n break;\n }\n case \"QueryFailed\": {\n const queryPath = this.queryPath(modification.queryId);\n if (queryPath) {\n for (const line of modification.logLines) {\n logForFunction(this.logger, \"info\", \"query\", queryPath, line);\n }\n }\n const { errorData } = modification;\n this.remoteQuerySet.set(modification.queryId, {\n success: false,\n errorMessage: modification.errorMessage,\n errorData:\n errorData !== undefined ? jsonToConvex(errorData) : undefined,\n logLines: modification.logLines,\n });\n break;\n }\n case \"QueryRemoved\": {\n this.remoteQuerySet.delete(modification.queryId);\n break;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n modification satisfies never;\n throw new Error(`Invalid modification ${(modification as any).type}`);\n }\n }\n }\n this.version = transition.endVersion;\n }\n\n remoteQueryResults(): Map<QueryId, FunctionResult> {\n return this.remoteQuerySet;\n }\n\n timestamp(): Long {\n return this.version.ts;\n }\n}\n", "import type { UserIdentityAttributes } from \"../../server/authentication.js\";\nexport type { UserIdentityAttributes } from \"../../server/authentication.js\";\nimport { JSONValue, Base64 } from \"../../values/index.js\";\nimport { Long } from \"../../vendor/long.js\";\n\n/**\n * Shared schema\n */\n\nexport function u64ToLong(encoded: EncodedU64): U64 {\n const integerBytes = Base64.toByteArray(encoded);\n return Long.fromBytesLE(Array.from(integerBytes));\n}\n\nexport function longToU64(raw: U64): EncodedU64 {\n const integerBytes = new Uint8Array(raw.toBytesLE());\n return Base64.fromByteArray(integerBytes);\n}\n\nexport function parseServerMessage(\n encoded: EncodedServerMessage,\n): WireServerMessage {\n switch (encoded.type) {\n case \"FatalError\":\n case \"AuthError\":\n case \"ActionResponse\":\n case \"TransitionChunk\":\n case \"Ping\": {\n return { ...encoded };\n }\n case \"MutationResponse\": {\n if (encoded.success) {\n return { ...encoded, ts: u64ToLong(encoded.ts) };\n } else {\n return { ...encoded };\n }\n }\n case \"Transition\": {\n return {\n ...encoded,\n startVersion: {\n ...encoded.startVersion,\n ts: u64ToLong(encoded.startVersion.ts),\n },\n endVersion: {\n ...encoded.endVersion,\n ts: u64ToLong(encoded.endVersion.ts),\n },\n };\n }\n default: {\n encoded satisfies never;\n }\n }\n return undefined as never;\n}\n\nexport function encodeClientMessage(\n message: ClientMessage,\n): EncodedClientMessage {\n switch (message.type) {\n case \"Authenticate\":\n case \"ModifyQuerySet\":\n case \"Mutation\":\n case \"Action\":\n case \"Event\": {\n return { ...message };\n }\n case \"Connect\": {\n if (message.maxObservedTimestamp !== undefined) {\n return {\n ...message,\n maxObservedTimestamp: longToU64(message.maxObservedTimestamp),\n };\n } else {\n return { ...message, maxObservedTimestamp: undefined };\n }\n }\n default: {\n message satisfies never;\n }\n }\n return undefined as never;\n}\n\ntype U64 = Long;\ntype EncodedU64 = string;\n\n/**\n * Unique nonnegative integer identifying a single query.\n */\nexport type QueryId = number; // nonnegative int\n\nexport type QuerySetVersion = number; // nonnegative int\n\nexport type RequestId = number; // nonnegative int\n\nexport type IdentityVersion = number; // nonnegative int\n\n/**\n * A serialized representation of decisions made during a query's execution.\n *\n * A journal is produced when a query function first executes and is re-used\n * when a query is re-executed.\n *\n * Currently this is used to store pagination end cursors to ensure\n * that pages of paginated queries will always end at the same cursor. This\n * enables gapless, reactive pagination.\n *\n * `null` is used to represent empty journals.\n * @public\n */\nexport type QueryJournal = string | null;\n\n/**\n * Client message schema\n */\n\ntype Connect = {\n type: \"Connect\";\n sessionId: string;\n connectionCount: number;\n lastCloseReason: string | null;\n maxObservedTimestamp?: TS | undefined;\n clientTs: number;\n};\n\nexport type AddQuery = {\n type: \"Add\";\n queryId: QueryId;\n udfPath: string;\n args: JSONValue[];\n journal?: QueryJournal | undefined;\n /**\n * @internal\n */\n componentPath?: string | undefined;\n};\n\nexport type RemoveQuery = {\n type: \"Remove\";\n queryId: QueryId;\n};\n\nexport type QuerySetModification = {\n type: \"ModifyQuerySet\";\n baseVersion: QuerySetVersion;\n newVersion: QuerySetVersion;\n modifications: (AddQuery | RemoveQuery)[];\n};\n\nexport type MutationRequest = {\n type: \"Mutation\";\n requestId: RequestId;\n udfPath: string;\n args: JSONValue[];\n // Execute the mutation on a specific component.\n // Only admin auth is allowed to run mutations on non-root components.\n componentPath?: string | undefined;\n};\n\nexport type ActionRequest = {\n type: \"Action\";\n requestId: RequestId;\n udfPath: string;\n args: JSONValue[];\n // Execute the action on a specific component.\n // Only admin auth is allowed to run actions on non-root components.\n componentPath?: string | undefined;\n};\n\nexport type AdminAuthentication = {\n type: \"Authenticate\";\n tokenType: \"Admin\";\n value: string;\n baseVersion: IdentityVersion;\n impersonating?: UserIdentityAttributes | undefined;\n};\n\nexport type Authenticate =\n | AdminAuthentication\n | {\n type: \"Authenticate\";\n tokenType: \"User\";\n value: string;\n baseVersion: IdentityVersion;\n }\n | {\n type: \"Authenticate\";\n tokenType: \"None\";\n baseVersion: IdentityVersion;\n };\n\nexport type Event = {\n type: \"Event\";\n eventType: string;\n event: any;\n};\nexport type ClientMessage =\n | Connect\n | Authenticate\n | QuerySetModification\n | MutationRequest\n | ActionRequest\n | Event;\n\ntype EncodedConnect = Omit<Connect, \"maxObservedTimestamp\"> & {\n maxObservedTimestamp?: EncodedTS | undefined;\n};\n\n// It's not a big deal to add `| undefined` to any optional properties here because\n// these messages are bound for JSON.stringify() serialization, which removes properties\n// that are undefined.\ntype EncodedClientMessage =\n | EncodedConnect\n | Authenticate\n | QuerySetModification\n | MutationRequest\n | ActionRequest\n | Event;\n\n/**\n * Server message schema\n */\nexport type TS = U64;\ntype EncodedTS = EncodedU64;\ntype LogLines = string[];\n\nexport type StateVersion = {\n querySet: QuerySetVersion;\n ts: TS;\n identity: IdentityVersion;\n};\ntype EncodedStateVersion = Omit<StateVersion, \"ts\"> & { ts: EncodedTS };\n\ntype StateModification =\n | {\n type: \"QueryUpdated\";\n queryId: QueryId;\n value: JSONValue;\n logLines: LogLines;\n journal: QueryJournal;\n }\n | {\n type: \"QueryFailed\";\n queryId: QueryId;\n errorMessage: string;\n logLines: LogLines;\n errorData: JSONValue;\n journal: QueryJournal;\n }\n | {\n type: \"QueryRemoved\";\n queryId: QueryId;\n };\n\nexport type Transition = {\n type: \"Transition\";\n startVersion: StateVersion;\n endVersion: StateVersion;\n modifications: StateModification[];\n clientClockSkew?: number;\n serverTs?: number;\n};\n\nexport type TransitionChunk = {\n type: \"TransitionChunk\";\n chunk: string;\n partNumber: number;\n totalParts: number;\n transitionId: string;\n};\n\ntype MutationSuccess = {\n type: \"MutationResponse\";\n requestId: RequestId;\n success: true;\n result: JSONValue;\n ts: TS;\n logLines: LogLines;\n};\ntype MutationFailed = {\n type: \"MutationResponse\";\n requestId: RequestId;\n success: false;\n result: string;\n logLines: LogLines;\n errorData?: JSONValue;\n};\nexport type MutationResponse = MutationSuccess | MutationFailed;\ntype ActionSuccess = {\n type: \"ActionResponse\";\n requestId: RequestId;\n success: true;\n result: JSONValue;\n logLines: LogLines;\n};\ntype ActionFailed = {\n type: \"ActionResponse\";\n requestId: RequestId;\n success: false;\n result: string;\n logLines: LogLines;\n errorData?: JSONValue;\n};\nexport type ActionResponse = ActionSuccess | ActionFailed;\nexport type AuthError = {\n type: \"AuthError\";\n error: string;\n baseVersion: IdentityVersion;\n // True if this error is in response to processing a new `Authenticate` message.\n // Other AuthErrors may occur due to executing a function with expired auth and\n // should be handled differently.\n authUpdateAttempted: boolean;\n};\ntype FatalError = {\n type: \"FatalError\";\n error: string;\n};\ntype Ping = {\n type: \"Ping\";\n};\n\n// Server Messages without the messages only visible to WebSocketManager\nexport type ServerMessage =\n | Transition\n | MutationResponse\n | ActionResponse\n | FatalError\n | AuthError;\n\nexport type WireServerMessage =\n | Transition\n | TransitionChunk\n | MutationResponse\n | ActionResponse\n | FatalError\n | AuthError\n | Ping;\n\ntype EncodedTransition = Omit<Transition, \"startVersion\" | \"endVersion\"> & {\n startVersion: EncodedStateVersion;\n endVersion: EncodedStateVersion;\n};\ntype EncodedMutationSuccess = Omit<MutationSuccess, \"ts\"> & { ts: EncodedTS };\ntype EncodedMutationResponse = MutationFailed | EncodedMutationSuccess;\n\ntype EncodedServerMessage =\n | EncodedTransition\n | TransitionChunk\n | EncodedMutationResponse\n | ActionResponse\n | FatalError\n | AuthError\n | Ping;\n", "import { Logger } from \"../logging.js\";\nimport {\n ClientMessage,\n encodeClientMessage,\n parseServerMessage,\n ServerMessage,\n Transition,\n TransitionChunk,\n} from \"./protocol.js\";\n\nconst CLOSE_NORMAL = 1000;\nconst CLOSE_GOING_AWAY = 1001;\nconst CLOSE_NO_STATUS = 1005;\n/** Convex-specific close code representing a \"404 Not Found\".\n * The edge Onramp accepts websocket upgrades before confirming that the\n * intended destination exists, so this code is sent once we've discovered that\n * the destination does not exist.\n */\nconst CLOSE_NOT_FOUND = 4040;\n\n/**\n * The various states our WebSocket can be in:\n *\n * - \"disconnected\": We don't have a WebSocket, but plan to create one.\n * - \"connecting\": We have created the WebSocket and are waiting for the\n * `onOpen` callback.\n * - \"ready\": We have an open WebSocket.\n * - \"stopped\": The WebSocket was closed and a new one can be created via `.restart()`.\n * - \"terminated\": We have closed the WebSocket and will never create a new one.\n *\n *\n * WebSocket State Machine\n * -----------------------\n * initialState: disconnected\n * validTransitions:\n * disconnected:\n * new WebSocket() -> connecting\n * terminate() -> terminated\n * connecting:\n * onopen -> ready\n * close() -> disconnected\n * terminate() -> terminated\n * ready:\n * close() -> disconnected\n * stop() -> stopped\n * terminate() -> terminated\n * stopped:\n * restart() -> connecting\n * terminate() -> terminated\n * terminalStates:\n * terminated\n *\n *\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u250C\u2500\u2500\u2500\u2500terminate()\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 disconnected \u2502\u25C0\u2500\u2510\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u25BC \u2502 \u25B2 \u2502\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 new WebSocket() \u2502 \u2502\n * \u250C\u2500\u25B6\u2502 terminated \u2502\u25C0\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2502 \u2502 \u2502\n * \u2502 \u25B2 terminate() \u2502 close() close()\n * \u2502 terminate() \u2502 \u2502 \u2502 \u2502\n * \u2502 \u2502 \u2502 \u25BC \u2502 \u2502\n * \u2502 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n * \u2502 \u2502 stopped \u2502\u2500\u2500restart()\u2500\u2500\u2500\u25B6\u2502 connecting \u2502 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n * \u2502 \u25B2 \u2502 \u2502\n * \u2502 \u2502 onopen \u2502\n * \u2502 \u2502 \u2502 \u2502\n * \u2502 \u2502 \u25BC \u2502\n * terminate() \u2502 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500stop()\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2502 ready \u2502\u2500\u2500\u2518\n * \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n * \u2502 \u2502\n * \u2502 \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * The `connecting` and `ready` state have a sub-state-machine for pausing.\n */\n\ntype Socket =\n | { state: \"disconnected\" }\n | { state: \"connecting\"; ws: WebSocket; paused: \"yes\" | \"no\" }\n | { state: \"ready\"; ws: WebSocket; paused: \"yes\" | \"no\" | \"uninitialized\" }\n | { state: \"stopped\" }\n | { state: \"terminated\" };\n\nexport type ReconnectMetadata = {\n connectionCount: number;\n lastCloseReason: string | null;\n clientTs: number;\n};\n\nexport type OnMessageResponse = {\n hasSyncedPastLastReconnect: boolean;\n};\n\nlet firstTime: number | undefined;\nfunction monotonicMillis() {\n if (firstTime === undefined) {\n firstTime = Date.now();\n }\n if (typeof performance === \"undefined\" || !performance.now) {\n return Date.now();\n }\n return Math.round(firstTime + performance.now());\n}\n\nfunction prettyNow() {\n return `t=${Math.round((monotonicMillis() - firstTime!) / 100) / 10}s`;\n}\n\nconst serverDisconnectErrors = {\n // A known error, e.g. during a restart or push\n InternalServerError: { timeout: 1000 },\n // ErrorMetadata::overloaded() messages that we realy should back off\n SubscriptionsWorkerFullError: { timeout: 3000 },\n TooManyConcurrentRequests: { timeout: 3000 },\n CommitterFullError: { timeout: 3000 },\n AwsTooManyRequestsException: { timeout: 3000 },\n ExecuteFullError: { timeout: 3000 },\n SystemTimeoutError: { timeout: 3000 },\n ExpiredInQueue: { timeout: 3000 },\n // ErrorMetadata::feature_temporarily_unavailable() that typically indicate a deploy just happened\n VectorIndexesUnavailable: { timeout: 1000 },\n SearchIndexesUnavailable: { timeout: 1000 },\n TableSummariesUnavailable: { timeout: 1000 },\n // More ErrorMetadata::overloaded()\n VectorIndexTooLarge: { timeout: 3000 },\n SearchIndexTooLarge: { timeout: 3000 },\n TooManyWritesInTimePeriod: { timeout: 3000 },\n} as const satisfies Record<string, { timeout: number }>;\n\ntype ServerDisconnectError = keyof typeof serverDisconnectErrors | \"Unknown\";\n\nfunction classifyDisconnectError(s?: string): ServerDisconnectError {\n if (s === undefined) return \"Unknown\";\n // startsWith so more info could be at the end (although currently there isn't)\n\n for (const prefix of Object.keys(\n serverDisconnectErrors,\n ) as ServerDisconnectError[]) {\n if (s.startsWith(prefix)) {\n return prefix;\n }\n }\n return \"Unknown\";\n}\n\n/**\n * A wrapper around a websocket that handles errors, reconnection, and message\n * parsing.\n */\nexport class WebSocketManager {\n private socket: Socket;\n\n private connectionCount: number;\n private _hasEverConnected: boolean = false;\n private lastCloseReason:\n | \"InitialConnect\"\n | \"OnCloseInvoked\"\n | (string & {}) // a full serverErrorReason (not just the prefix) or a new one\n | null;\n\n // State for assembling the split-up Transition currently being received.\n private transitionChunkBuffer: {\n chunks: string[];\n totalParts: number;\n transitionId: string;\n } | null = null;\n\n /** Upon HTTPS/WSS failure, the first jittered backoff duration, in ms. */\n private readonly defaultInitialBackoff: number;\n\n /** We backoff exponentially, but we need to cap that--this is the jittered max. */\n private readonly maxBackoff: number;\n\n /** How many times have we failed consecutively? */\n private retries: number;\n\n /** How long before lack of server response causes us to initiate a reconnect,\n * in ms */\n private readonly serverInactivityThreshold: number;\n\n private reconnectDueToServerInactivityTimeout: ReturnType<\n typeof setTimeout\n > | null;\n\n /** Scheduled reconnect state: timeout handle and timing info */\n private scheduledReconnect: {\n timeout: ReturnType<typeof setTimeout>;\n scheduledAt: number;\n backoffMs: number;\n } | null = null;\n\n private networkOnlineHandler: (() => void) | null = null;\n\n /** Pending event to send after reconnecting due to network recovery */\n private pendingNetworkRecoveryInfo: { timeSavedMs: number } | null = null;\n\n private readonly uri: string;\n private readonly onOpen: (reconnectMetadata: ReconnectMetadata) => void;\n private readonly onResume: () => void;\n private readonly onMessage: (message: ServerMessage) => OnMessageResponse;\n private readonly webSocketConstructor: typeof WebSocket;\n private readonly logger: Logger;\n private readonly onServerDisconnectError:\n | ((message: string) => void)\n | undefined;\n\n constructor(\n uri: string,\n callbacks: {\n onOpen: (reconnectMetadata: ReconnectMetadata) => void;\n onResume: () => void;\n onMessage: (message: ServerMessage) => OnMessageResponse;\n onServerDisconnectError?: ((message: string) => void) | undefined;\n },\n webSocketConstructor: typeof WebSocket,\n logger: Logger,\n private readonly markConnectionStateDirty: () => void,\n private readonly debug: boolean,\n ) {\n this.webSocketConstructor = webSocketConstructor;\n this.socket = { state: \"disconnected\" };\n this.connectionCount = 0;\n this.lastCloseReason = \"InitialConnect\";\n\n // backoff for unknown errors\n this.defaultInitialBackoff = 1000;\n this.maxBackoff = 16000;\n this.retries = 0;\n\n // Ping messages (sync protocol Pings, not WebSocket protocol Pings) are\n // sent every 15s in the absence of other messages. But a single large\n // Transition or other downstream message can hog the line so this\n // threshold is set higher to prevent clients from giving up.\n this.serverInactivityThreshold = 60000;\n this.reconnectDueToServerInactivityTimeout = null;\n\n this.uri = uri;\n this.onOpen = callbacks.onOpen;\n this.onResume = callbacks.onResume;\n this.onMessage = callbacks.onMessage;\n this.onServerDisconnectError = callbacks.onServerDisconnectError;\n this.logger = logger;\n\n // Set up network online event listener\n this.setupNetworkListener();\n\n this.connect();\n }\n\n private setSocketState(state: Socket) {\n this.socket = state;\n this._logVerbose(\n `socket state changed: ${this.socket.state}, paused: ${\n \"paused\" in this.socket ? this.socket.paused : undefined\n }`,\n );\n this.markConnectionStateDirty();\n }\n\n private setupNetworkListener() {\n // Only set up listener if we're in a browser environment with addEventListener\n // (React Native has window but not addEventListener)\n if (\n typeof window === \"undefined\" ||\n typeof window.addEventListener !== \"function\"\n ) {\n return;\n }\n // Avoid registering duplicate listeners\n if (this.networkOnlineHandler !== null) {\n return;\n }\n\n this.networkOnlineHandler = () => {\n this._logVerbose(\"network online event detected\");\n this.tryReconnectImmediately();\n };\n\n window.addEventListener(\"online\", this.networkOnlineHandler);\n this._logVerbose(\"network online event listener registered\");\n }\n\n private cleanupNetworkListener() {\n if (\n this.networkOnlineHandler &&\n typeof window !== \"undefined\" &&\n typeof window.removeEventListener === \"function\"\n ) {\n window.removeEventListener(\"online\", this.networkOnlineHandler);\n this.networkOnlineHandler = null;\n this._logVerbose(\"network online event listener removed\");\n }\n }\n\n private assembleTransition(chunk: TransitionChunk): Transition | null {\n if (\n chunk.partNumber < 0 ||\n chunk.partNumber >= chunk.totalParts ||\n chunk.totalParts === 0 ||\n (this.transitionChunkBuffer &&\n (this.transitionChunkBuffer.totalParts !== chunk.totalParts ||\n this.transitionChunkBuffer.transitionId !== chunk.transitionId))\n ) {\n // Throwing an error doesn't crash the client, so clear the buffer.\n this.transitionChunkBuffer = null;\n throw new Error(\"Invalid TransitionChunk\");\n }\n\n if (this.transitionChunkBuffer === null) {\n this.transitionChunkBuffer = {\n chunks: [],\n totalParts: chunk.totalParts,\n transitionId: chunk.transitionId,\n };\n }\n\n if (chunk.partNumber !== this.transitionChunkBuffer.chunks.length) {\n // Throwing an error doesn't crash the client, so clear the buffer.\n const expectedLength = this.transitionChunkBuffer.chunks.length;\n this.transitionChunkBuffer = null;\n throw new Error(\n `TransitionChunk received out of order: expected part ${expectedLength}, got ${chunk.partNumber}`,\n );\n }\n\n this.transitionChunkBuffer.chunks.push(chunk.chunk);\n\n if (this.transitionChunkBuffer.chunks.length === chunk.totalParts) {\n const fullJson = this.transitionChunkBuffer.chunks.join(\"\");\n this.transitionChunkBuffer = null;\n\n const transition = parseServerMessage(JSON.parse(fullJson));\n if (transition.type !== \"Transition\") {\n throw new Error(\n `Expected Transition, got ${transition.type} after assembling chunks`,\n );\n }\n return transition;\n }\n\n return null;\n }\n\n private connect() {\n if (this.socket.state === \"terminated\") {\n return;\n }\n if (\n this.socket.state !== \"disconnected\" &&\n this.socket.state !== \"stopped\"\n ) {\n throw new Error(\n \"Didn't start connection from disconnected state: \" + this.socket.state,\n );\n }\n\n const ws = new this.webSocketConstructor(this.uri);\n this._logVerbose(\"constructed WebSocket\");\n this.setSocketState({\n state: \"connecting\",\n ws,\n paused: \"no\",\n });\n\n // Kick off server inactivity timer before WebSocket connection is established\n // so we can detect cases where handshake fails.\n // The `onopen` event only fires after the connection is established:\n // Source: https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\n this.resetServerInactivityTimeout();\n\n ws.onopen = () => {\n this.logger.logVerbose(\"begin ws.onopen\");\n if (this.socket.state !== \"connecting\") {\n throw new Error(\"onopen called with socket not in connecting state\");\n }\n this.setSocketState({\n state: \"ready\",\n ws,\n paused: this.socket.paused === \"yes\" ? \"uninitialized\" : \"no\",\n });\n this.resetServerInactivityTimeout();\n if (this.socket.paused === \"no\") {\n this._hasEverConnected = true;\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n clientTs: monotonicMillis(),\n });\n }\n\n if (this.lastCloseReason !== \"InitialConnect\") {\n if (this.lastCloseReason) {\n this.logger.log(\n \"WebSocket reconnected at\",\n prettyNow(),\n \"after disconnect due to\",\n this.lastCloseReason,\n );\n } else {\n this.logger.log(\"WebSocket reconnected at\", prettyNow());\n }\n }\n\n this.connectionCount += 1;\n this.lastCloseReason = null;\n\n // Send event for network recovery reconnect if applicable\n if (this.pendingNetworkRecoveryInfo !== null) {\n const { timeSavedMs } = this.pendingNetworkRecoveryInfo;\n this.pendingNetworkRecoveryInfo = null;\n this.sendMessage({\n type: \"Event\",\n eventType: \"NetworkRecoveryReconnect\",\n event: { timeSavedMs },\n });\n this.logger.log(\n `Network recovery reconnect saved ~${Math.round(timeSavedMs / 1000)}s of waiting`,\n );\n }\n };\n // NB: The WebSocket API calls `onclose` even if connection fails, so we can route all error paths through `onclose`.\n ws.onerror = (error) => {\n this.transitionChunkBuffer = null;\n const message = (error as ErrorEvent).message;\n if (message) {\n this.logger.log(`WebSocket error message: ${message}`);\n }\n };\n ws.onmessage = (message) => {\n this.resetServerInactivityTimeout();\n const messageLength = message.data.length;\n let serverMessage = parseServerMessage(JSON.parse(message.data));\n this._logVerbose(`received ws message with type ${serverMessage.type}`);\n\n // Ping's only purpose is to reset the server inactivity timer.\n if (serverMessage.type === \"Ping\") {\n return;\n }\n\n // TransitionChunks never reach the main client logic.\n if (serverMessage.type === \"TransitionChunk\") {\n const transition = this.assembleTransition(serverMessage);\n if (!transition) {\n return;\n }\n serverMessage = transition;\n this._logVerbose(\n `assembled full ws message of type ${serverMessage.type}`,\n );\n }\n\n if (this.transitionChunkBuffer !== null) {\n this.transitionChunkBuffer = null;\n this.logger.log(\n `Received unexpected ${serverMessage.type} while buffering TransitionChunks`,\n );\n }\n\n if (serverMessage.type === \"Transition\") {\n this.reportLargeTransition({\n messageLength,\n transition: serverMessage,\n });\n }\n const response = this.onMessage(serverMessage);\n if (response.hasSyncedPastLastReconnect) {\n // Reset backoff to 0 once all outstanding requests are complete.\n this.retries = 0;\n this.markConnectionStateDirty();\n }\n };\n ws.onclose = (event) => {\n this._logVerbose(\"begin ws.onclose\");\n this.transitionChunkBuffer = null;\n if (this.lastCloseReason === null) {\n // event.reason is often an empty string\n this.lastCloseReason = event.reason || `closed with code ${event.code}`;\n }\n if (\n event.code !== CLOSE_NORMAL &&\n event.code !== CLOSE_GOING_AWAY && // This commonly gets fired on mobile apps when the app is backgrounded\n event.code !== CLOSE_NO_STATUS &&\n event.code !== CLOSE_NOT_FOUND // Note that we want to retry on a 404, as it can be transient during a push.\n ) {\n let msg = `WebSocket closed with code ${event.code}`;\n if (event.reason) {\n msg += `: ${event.reason}`;\n }\n this.logger.log(msg);\n if (this.onServerDisconnectError && event.reason) {\n // This callback is a unstable API, InternalServerErrors in particular may be removed\n // since they reflect expected temporary downtime. But until a quantitative measure\n // of uptime is reported this unstable API errs on the inclusive side.\n this.onServerDisconnectError(msg);\n }\n }\n const reason = classifyDisconnectError(event.reason);\n this.scheduleReconnect(reason);\n return;\n };\n }\n\n /**\n * @returns The state of the {@link Socket}.\n */\n socketState(): string {\n return this.socket.state;\n }\n\n /**\n * @param message - A ClientMessage to send.\n * @returns Whether the message (might have been) sent.\n */\n sendMessage(message: ClientMessage) {\n const messageForLog = {\n type: message.type,\n ...(message.type === \"Authenticate\" && message.tokenType === \"User\"\n ? {\n value: `...${message.value.slice(-7)}`,\n }\n : {}),\n };\n if (this.socket.state === \"ready\" && this.socket.paused === \"no\") {\n const encodedMessage = encodeClientMessage(message);\n const request = JSON.stringify(encodedMessage);\n let sent = false;\n try {\n this.socket.ws.send(request);\n sent = true;\n } catch (error: any) {\n this.logger.log(\n `Failed to send message on WebSocket, reconnecting: ${error}`,\n );\n this.closeAndReconnect(\"FailedToSendMessage\");\n }\n this._logVerbose(\n `${sent ? \"sent\" : \"failed to send\"} message with type ${message.type}: ${JSON.stringify(\n messageForLog,\n )}`,\n );\n return true;\n }\n this._logVerbose(\n `message not sent (socket state: ${this.socket.state}, paused: ${\"paused\" in this.socket ? this.socket.paused : undefined}): ${JSON.stringify(\n messageForLog,\n )}`,\n );\n\n return false;\n }\n\n private resetServerInactivityTimeout() {\n if (this.socket.state === \"terminated\") {\n // Don't reset any timers if we were trying to terminate.\n return;\n }\n if (this.reconnectDueToServerInactivityTimeout !== null) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n this.reconnectDueToServerInactivityTimeout = null;\n }\n this.reconnectDueToServerInactivityTimeout = setTimeout(() => {\n this.closeAndReconnect(\"InactiveServer\");\n }, this.serverInactivityThreshold);\n }\n\n private scheduleReconnect(reason: \"client\" | ServerDisconnectError) {\n // Cancel any existing scheduled reconnect to avoid multiple reconnects\n if (this.scheduledReconnect) {\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n }\n\n this.socket = { state: \"disconnected\" };\n const backoff = this.nextBackoff(reason);\n this.markConnectionStateDirty();\n this.logger.log(`Attempting reconnect in ${Math.round(backoff)}ms`);\n\n const scheduledAt = monotonicMillis();\n const timeoutId = setTimeout(() => {\n // Only proceed if this timeout hasn't been cleared\n if (this.scheduledReconnect?.timeout === timeoutId) {\n this.scheduledReconnect = null;\n this.connect();\n }\n }, backoff);\n\n this.scheduledReconnect = {\n timeout: timeoutId,\n scheduledAt,\n backoffMs: backoff,\n };\n }\n\n /**\n * Close the WebSocket and schedule a reconnect.\n *\n * This should be used when we hit an error and would like to restart the session.\n */\n private closeAndReconnect(closeReason: string) {\n this._logVerbose(`begin closeAndReconnect with reason ${closeReason}`);\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n // Nothing to do if we don't have a WebSocket.\n return;\n case \"connecting\":\n case \"ready\": {\n this.lastCloseReason = closeReason;\n // Close the old socket asynchronously, we'll open a new socket in reconnect.\n void this.close();\n this.scheduleReconnect(\"client\");\n return;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n }\n }\n }\n\n /**\n * Close the WebSocket, being careful to clear the onclose handler to avoid re-entrant\n * calls. Use this instead of directly calling `ws.close()`\n *\n * It is the callers responsibility to update the state after this method is called so that the\n * closed socket is not accessible or used again after this method is called\n */\n private close(): Promise<void> {\n this.transitionChunkBuffer = null;\n switch (this.socket.state) {\n case \"disconnected\":\n case \"terminated\":\n case \"stopped\":\n // Nothing to do if we don't have a WebSocket.\n return Promise.resolve();\n case \"connecting\": {\n const ws = this.socket.ws;\n // Messages can still be received after close but we're not interested.\n ws.onmessage = (_message) => {\n this._logVerbose(\"Ignoring message received after close\");\n };\n return new Promise((r) => {\n ws.onclose = () => {\n this._logVerbose(\"Closed after connecting\");\n r();\n };\n ws.onopen = () => {\n this._logVerbose(\"Opened after connecting\");\n ws.close();\n };\n });\n }\n case \"ready\": {\n this._logVerbose(\"ws.close called\");\n const ws = this.socket.ws;\n // Messages can still be received after close but we're not interested.\n ws.onmessage = (_message) => {\n this._logVerbose(\"Ignoring message received after close\");\n };\n const result: Promise<void> = new Promise((r) => {\n ws.onclose = () => {\n r();\n };\n });\n ws.close();\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n return Promise.resolve();\n }\n }\n }\n\n /**\n * Close the WebSocket and do not reconnect.\n * @returns A Promise that resolves when the WebSocket `onClose` callback is called.\n */\n terminate(): Promise<void> {\n if (this.reconnectDueToServerInactivityTimeout) {\n clearTimeout(this.reconnectDueToServerInactivityTimeout);\n }\n if (this.scheduledReconnect) {\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n }\n this.cleanupNetworkListener();\n switch (this.socket.state) {\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n case \"connecting\":\n case \"ready\": {\n const result = this.close();\n this.setSocketState({ state: \"terminated\" });\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n throw new Error(\n `Invalid websocket state: ${(this.socket as any).state}`,\n );\n }\n }\n }\n\n stop(): Promise<void> {\n switch (this.socket.state) {\n case \"terminated\":\n // If we're terminating we ignore stop\n return Promise.resolve();\n case \"connecting\":\n case \"stopped\":\n case \"disconnected\":\n case \"ready\": {\n this.cleanupNetworkListener();\n const result = this.close();\n this.socket = { state: \"stopped\" };\n return result;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n return Promise.resolve();\n }\n }\n }\n\n /**\n * Create a new WebSocket after a previous `stop()`, unless `terminate()` was\n * called before.\n */\n tryRestart(): void {\n switch (this.socket.state) {\n case \"stopped\":\n break;\n case \"terminated\":\n case \"connecting\":\n case \"ready\":\n case \"disconnected\":\n this.logger.logVerbose(\"Restart called without stopping first\");\n return;\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n }\n }\n this.setupNetworkListener();\n this.connect();\n }\n\n pause(): void {\n switch (this.socket.state) {\n case \"disconnected\":\n case \"stopped\":\n case \"terminated\":\n // If already stopped or stopping ignore.\n return;\n case \"connecting\":\n case \"ready\": {\n this.socket = { ...this.socket, paused: \"yes\" };\n return;\n }\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n return;\n }\n }\n }\n\n /**\n * Try to reconnect immediately, canceling any scheduled reconnect.\n * This is useful when detecting network recovery.\n * Only takes action if we're in disconnected state (waiting to reconnect).\n */\n tryReconnectImmediately(): void {\n this._logVerbose(\"tryReconnectImmediately called\");\n\n // Only reconnect if we're in disconnected state (waiting to reconnect)\n if (this.socket.state !== \"disconnected\") {\n this._logVerbose(\n `tryReconnectImmediately called but socket state is ${this.socket.state}, no action taken`,\n );\n return;\n }\n\n // Track how much time we saved by reconnecting immediately\n let timeSavedMs: number | null = null;\n if (this.scheduledReconnect) {\n const elapsed = monotonicMillis() - this.scheduledReconnect.scheduledAt;\n timeSavedMs = Math.max(0, this.scheduledReconnect.backoffMs - elapsed);\n this._logVerbose(\n `would have waited ${Math.round(timeSavedMs)}ms more (backoff was ${Math.round(this.scheduledReconnect.backoffMs)}ms, elapsed ${Math.round(elapsed)}ms)`,\n );\n // Cancel the scheduled reconnect\n clearTimeout(this.scheduledReconnect.timeout);\n this.scheduledReconnect = null;\n this._logVerbose(\"canceled scheduled reconnect\");\n }\n\n this.logger.log(\"Network recovery detected, reconnecting immediately\");\n // Store the time saved to send as an event after we connect\n this.pendingNetworkRecoveryInfo =\n timeSavedMs !== null ? { timeSavedMs } : null;\n this.connect();\n }\n\n /**\n * Resume the state machine if previously paused.\n */\n resume(): void {\n switch (this.socket.state) {\n case \"connecting\":\n this.socket = { ...this.socket, paused: \"no\" };\n return;\n case \"ready\":\n if (this.socket.paused === \"uninitialized\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onOpen({\n connectionCount: this.connectionCount,\n lastCloseReason: this.lastCloseReason,\n clientTs: monotonicMillis(),\n });\n } else if (this.socket.paused === \"yes\") {\n this.socket = { ...this.socket, paused: \"no\" };\n this.onResume();\n }\n return;\n case \"terminated\":\n case \"stopped\":\n case \"disconnected\":\n // Ignore resume if not paused, perhaps we already resumed.\n return;\n default: {\n // Enforce that the switch-case is exhaustive.\n this.socket satisfies never;\n }\n }\n this.connect();\n }\n\n connectionState(): {\n isConnected: boolean;\n hasEverConnected: boolean;\n connectionCount: number;\n connectionRetries: number;\n } {\n return {\n isConnected: this.socket.state === \"ready\",\n hasEverConnected: this._hasEverConnected,\n connectionCount: this.connectionCount,\n connectionRetries: this.retries,\n };\n }\n\n private _logVerbose(message: string) {\n this.logger.logVerbose(message);\n }\n\n private nextBackoff(reason: \"client\" | ServerDisconnectError): number {\n const initialBackoff: number =\n reason === \"client\"\n ? 100 // There's no evidence of a server problem, retry quickly\n : reason === \"Unknown\"\n ? this.defaultInitialBackoff\n : serverDisconnectErrors[reason].timeout;\n\n const baseBackoff = initialBackoff * Math.pow(2, this.retries);\n this.retries += 1;\n const actualBackoff = Math.min(baseBackoff, this.maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n }\n\n private reportLargeTransition({\n transition,\n messageLength,\n }: {\n transition: Transition;\n messageLength: number;\n }) {\n if (\n transition.clientClockSkew === undefined ||\n transition.serverTs === undefined\n ) {\n return;\n }\n\n const transitionTransitTime =\n monotonicMillis() - // client time now\n // clientClockSkew = (server time + upstream latency) - client time\n // clientClockSkew is \"how many milliseconds behind (slow) is the client clock\"\n // but the latency of the Connect message inflates this, making it appear further behind\n transition.clientClockSkew -\n transition.serverTs / 1_000_000; // server time when transition was sent\n const prettyTransitionTime = `${Math.round(transitionTransitTime)}ms`;\n const prettyMessageMB = `${Math.round(messageLength / 10_000) / 100}MB`;\n const bytesPerSecond = messageLength / (transitionTransitTime / 1000);\n const prettyBytesPerSecond = `${Math.round(bytesPerSecond / 10_000) / 100}MB per second`;\n this._logVerbose(\n `received ${prettyMessageMB} transition in ${prettyTransitionTime} at ${prettyBytesPerSecond}`,\n );\n\n // Warnings that will show up for *all users*, so don't be too aggressive.\n // These can be silenced (along with reconnection messages) by setting `logger: false` in client options.\n if (messageLength > 20_000_000) {\n // Big enough that the developer should be made aware of this.\n this.logger.log(\n `received query results totaling more that 20MB (${prettyMessageMB}) which will take a long time to download on slower connections`,\n );\n } else if (transitionTransitTime > 20_000) {\n // Long enough that a pattern of these should be interesting to a developer, but be aware that\n // weak connections, putting clients to sleep, backgrounding etc. could all cause this too.\n this.logger.log(\n `received query results totaling ${prettyMessageMB} which took more than 20s to arrive (${prettyTransitionTime})`,\n );\n }\n\n if (this.debug) {\n // debug means \"reportDebugInfoToConvex\" is set so this can be aggressive.\n this.sendMessage({\n type: \"Event\",\n eventType: \"ClientReceivedTransition\",\n event: { transitionTransitTime, messageLength },\n });\n }\n }\n}\n", "export function newSessionId() {\n return uuidv4();\n}\n\n// From https://stackoverflow.com/a/2117523\nfunction uuidv4() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0,\n v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n", "export interface JwtDecodeOptions {\n header?: boolean;\n}\n\nexport interface JwtHeader {\n typ?: string;\n alg?: string;\n kid?: string;\n}\n\nexport interface JwtPayload {\n iss?: string;\n sub?: string;\n aud?: string[] | string;\n exp?: number;\n nbf?: number;\n iat?: number;\n jti?: string;\n}\n\nexport class InvalidTokenError extends Error {}\n\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\n\nfunction b64DecodeUnicode(str: string) {\n return decodeURIComponent(\n atob(str).replace(/(.)/g, (_m, p) => {\n let code = (p as string).charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n }),\n );\n}\n\nfunction base64UrlDecode(str: string) {\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw new Error(\"base64 string is not of the correct length\");\n }\n\n try {\n return b64DecodeUnicode(output);\n } catch {\n return atob(output);\n }\n}\n\nexport function jwtDecode<T = JwtHeader>(\n token: string,\n options: JwtDecodeOptions & { header: true },\n): T;\nexport function jwtDecode<T = JwtPayload>(\n token: string,\n options?: JwtDecodeOptions,\n): T;\nexport function jwtDecode<T = JwtHeader | JwtPayload>(\n token: string,\n options?: JwtDecodeOptions,\n): T {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\n }\n\n options ||= {};\n\n const pos = options.header === true ? 0 : 1;\n const part = token.split(\".\")[pos];\n\n if (typeof part !== \"string\") {\n throw new InvalidTokenError(\n `Invalid token specified: missing part #${pos + 1}`,\n );\n }\n\n let decoded: string;\n try {\n decoded = base64UrlDecode(part);\n } catch (e) {\n throw new InvalidTokenError(\n `Invalid token specified: invalid base64 for part #${pos + 1} (${(e as Error).message})`,\n );\n }\n\n try {\n return JSON.parse(decoded) as T;\n } catch (e) {\n throw new InvalidTokenError(\n `Invalid token specified: invalid json for part #${pos + 1} (${(e as Error).message})`,\n );\n }\n}\n", "import { Logger } from \"../logging.js\";\nimport { LocalSyncState } from \"./local_state.js\";\nimport { AuthError, IdentityVersion, Transition } from \"./protocol.js\";\nimport { jwtDecode } from \"../../vendor/jwt-decode/index.js\";\n\n// setTimout uses 32 bit integer, so it can only\n// schedule about 24 days in the future.\nconst MAXIMUM_REFRESH_DELAY = 20 * 24 * 60 * 60 * 1000; // 20 days\n\nconst MAX_TOKEN_CONFIRMATION_ATTEMPTS = 2;\n\n/**\n * An async function returning a JWT. Depending on the auth providers\n * configured in convex/auth.config.ts, this may be a JWT-encoded OpenID\n * Connect Identity Token or a traditional JWT.\n *\n * `forceRefreshToken` is `true` if the server rejected a previously\n * returned token or the token is anticipated to expiring soon\n * based on its `exp` time.\n *\n * See {@link ConvexReactClient.setAuth}.\n *\n * @public\n */\nexport type AuthTokenFetcher = (args: {\n forceRefreshToken: boolean;\n}) => Promise<string | null | undefined>;\n\n/**\n * What is provided to the client.\n */\ntype AuthConfig = {\n fetchToken: AuthTokenFetcher;\n onAuthChange: (isAuthenticated: boolean) => void;\n};\n\n/**\n * In general we take 3 steps:\n * 1. Fetch a possibly cached token\n * 2. Immediately fetch a fresh token without using a cache\n * 3. Repeat step 2 before the end of the fresh token's lifetime\n *\n * When we fetch without using a cache we know when the token\n * will expire, and can schedule refetching it.\n *\n * If we get an error before a scheduled refetch, we go back\n * to step 2.\n */\ntype AuthState =\n | { state: \"noAuth\" }\n | {\n state: \"waitingForServerConfirmationOfCachedToken\";\n config: AuthConfig;\n hasRetried: boolean;\n }\n | {\n state: \"initialRefetch\";\n config: AuthConfig;\n }\n | {\n state: \"waitingForServerConfirmationOfFreshToken\";\n config: AuthConfig;\n hadAuth: boolean;\n token: string;\n }\n | {\n state: \"waitingForScheduledRefetch\";\n config: AuthConfig;\n refetchTokenTimeoutId: ReturnType<typeof setTimeout>;\n }\n // Special/weird state when we got a valid token\n // but could not fetch a new one.\n | {\n state: \"notRefetching\";\n config: AuthConfig;\n };\n\n/**\n * Handles the state transitions for auth. The server is the source\n * of truth.\n */\nexport class AuthenticationManager {\n private authState: AuthState = { state: \"noAuth\" };\n // Used to detect races involving `setConfig` calls\n // while a token is being fetched.\n private configVersion = 0;\n // Shared by the BaseClient so that the auth manager can easily inspect it\n private readonly syncState: LocalSyncState;\n // Passed down by BaseClient, sends a message to the server\n private readonly authenticate: (token: string) => IdentityVersion;\n private readonly stopSocket: () => Promise<void>;\n private readonly tryRestartSocket: () => void;\n private readonly pauseSocket: () => void;\n private readonly resumeSocket: () => void;\n // Passed down by BaseClient, sends a message to the server\n private readonly clearAuth: () => void;\n private readonly logger: Logger;\n private readonly refreshTokenLeewaySeconds: number;\n // Number of times we have attempted to confirm the latest token. We retry up\n // to `MAX_TOKEN_CONFIRMATION_ATTEMPTS` times.\n private tokenConfirmationAttempts = 0;\n constructor(\n syncState: LocalSyncState,\n callbacks: {\n authenticate: (token: string) => IdentityVersion;\n stopSocket: () => Promise<void>;\n tryRestartSocket: () => void;\n pauseSocket: () => void;\n resumeSocket: () => void;\n clearAuth: () => void;\n },\n config: {\n refreshTokenLeewaySeconds: number;\n logger: Logger;\n },\n ) {\n this.syncState = syncState;\n this.authenticate = callbacks.authenticate;\n this.stopSocket = callbacks.stopSocket;\n this.tryRestartSocket = callbacks.tryRestartSocket;\n this.pauseSocket = callbacks.pauseSocket;\n this.resumeSocket = callbacks.resumeSocket;\n this.clearAuth = callbacks.clearAuth;\n this.logger = config.logger;\n this.refreshTokenLeewaySeconds = config.refreshTokenLeewaySeconds;\n }\n\n async setConfig(\n fetchToken: AuthTokenFetcher,\n onChange: (isAuthenticated: boolean) => void,\n ) {\n this.resetAuthState();\n this._logVerbose(\"pausing WS for auth token fetch\");\n this.pauseSocket();\n const token = await this.fetchTokenAndGuardAgainstRace(fetchToken, {\n forceRefreshToken: false,\n });\n if (token.isFromOutdatedConfig) {\n return;\n }\n if (token.value) {\n this.setAuthState({\n state: \"waitingForServerConfirmationOfCachedToken\",\n config: { fetchToken, onAuthChange: onChange },\n hasRetried: false,\n });\n this.authenticate(token.value);\n } else {\n this.setAuthState({\n state: \"initialRefetch\",\n config: { fetchToken, onAuthChange: onChange },\n });\n // Try again with `forceRefreshToken: true`\n await this.refetchToken();\n }\n this._logVerbose(\"resuming WS after auth token fetch\");\n this.resumeSocket();\n }\n\n onTransition(serverMessage: Transition) {\n if (\n !this.syncState.isCurrentOrNewerAuthVersion(\n serverMessage.endVersion.identity,\n )\n ) {\n // This is a stale transition - client has moved on to\n // a newer auth version.\n return;\n }\n if (\n serverMessage.endVersion.identity <= serverMessage.startVersion.identity\n ) {\n // This transition did not change auth - it is not a response to Authenticate.\n return;\n }\n\n this._logVerbose(\n `auth state is ${this.authState.state} when handling transition`,\n );\n\n // This transition advanced the auth version, which means the token used was valid\n // and the client and server auth states are in sync.\n this.syncState.markAuthCompletion();\n\n if (this.authState.state === \"waitingForServerConfirmationOfCachedToken\") {\n this._logVerbose(\"server confirmed auth token is valid\");\n void this.refetchToken();\n this.authState.config.onAuthChange(true);\n return;\n }\n if (this.authState.state === \"waitingForServerConfirmationOfFreshToken\") {\n this._logVerbose(\"server confirmed new auth token is valid\");\n this.scheduleTokenRefetch(this.authState.token);\n this.tokenConfirmationAttempts = 0;\n if (!this.authState.hadAuth) {\n this.authState.config.onAuthChange(true);\n }\n }\n }\n\n onAuthError(serverMessage: AuthError) {\n // If the AuthError is not due to updating the token, and we're currently\n // waiting on the result of a token update, ignore.\n if (\n serverMessage.authUpdateAttempted === false &&\n (this.authState.state === \"waitingForServerConfirmationOfFreshToken\" ||\n this.authState.state === \"waitingForServerConfirmationOfCachedToken\")\n ) {\n this._logVerbose(\"ignoring non-auth token expired error\");\n return;\n }\n const { baseVersion } = serverMessage;\n // Versioned AuthErrors are ignored if the client advanced to\n // a newer auth identity\n // Error are reporting the previous version, since the server\n // didn't advance, hence `+ 1`.\n if (!this.syncState.isCurrentOrNewerAuthVersion(baseVersion + 1)) {\n this._logVerbose(\"ignoring auth error for previous auth attempt\");\n return;\n }\n void this.tryToReauthenticate(serverMessage);\n return;\n }\n\n // This is similar to `refetchToken` defined below, in fact we\n // don't represent them as different states, but it is different\n // in that we pause the WebSocket so that mutations\n // don't retry with bad auth.\n private async tryToReauthenticate(serverMessage: AuthError) {\n this._logVerbose(`attempting to reauthenticate: ${serverMessage.error}`);\n if (\n // No way to fetch another token, kaboom\n this.authState.state === \"noAuth\" ||\n // We failed on a fresh token. After a small number of retries, we give up\n // and clear the auth state to avoid infinite retries.\n (this.authState.state === \"waitingForServerConfirmationOfFreshToken\" &&\n this.tokenConfirmationAttempts >= MAX_TOKEN_CONFIRMATION_ATTEMPTS)\n ) {\n this.logger.error(\n `Failed to authenticate: \"${serverMessage.error}\", check your server auth config`,\n );\n if (this.syncState.hasAuth()) {\n this.syncState.clearAuth();\n }\n if (this.authState.state !== \"noAuth\") {\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n return;\n }\n if (this.authState.state === \"waitingForServerConfirmationOfFreshToken\") {\n this.tokenConfirmationAttempts++;\n this._logVerbose(\n `retrying reauthentication, ${MAX_TOKEN_CONFIRMATION_ATTEMPTS - this.tokenConfirmationAttempts} attempts remaining`,\n );\n }\n\n await this.stopSocket();\n const token = await this.fetchTokenAndGuardAgainstRace(\n this.authState.config.fetchToken,\n {\n forceRefreshToken: true,\n },\n );\n if (token.isFromOutdatedConfig) {\n return;\n }\n\n if (token.value && this.syncState.isNewAuth(token.value)) {\n this.authenticate(token.value);\n this.setAuthState({\n state: \"waitingForServerConfirmationOfFreshToken\",\n config: this.authState.config,\n token: token.value,\n hadAuth:\n this.authState.state === \"notRefetching\" ||\n this.authState.state === \"waitingForScheduledRefetch\",\n });\n } else {\n this._logVerbose(\"reauthentication failed, could not fetch a new token\");\n if (this.syncState.hasAuth()) {\n this.syncState.clearAuth();\n }\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n this.tryRestartSocket();\n }\n\n // Force refetch the token and schedule another refetch\n // before the token expires - an active client should never\n // need to reauthenticate.\n private async refetchToken() {\n if (this.authState.state === \"noAuth\") {\n return;\n }\n this._logVerbose(\"refetching auth token\");\n const token = await this.fetchTokenAndGuardAgainstRace(\n this.authState.config.fetchToken,\n {\n forceRefreshToken: true,\n },\n );\n if (token.isFromOutdatedConfig) {\n return;\n }\n\n if (token.value) {\n if (this.syncState.isNewAuth(token.value)) {\n this.setAuthState({\n state: \"waitingForServerConfirmationOfFreshToken\",\n hadAuth: this.syncState.hasAuth(),\n token: token.value,\n config: this.authState.config,\n });\n this.authenticate(token.value);\n } else {\n this.setAuthState({\n state: \"notRefetching\",\n config: this.authState.config,\n });\n }\n } else {\n this._logVerbose(\"refetching token failed\");\n if (this.syncState.hasAuth()) {\n this.clearAuth();\n }\n this.setAndReportAuthFailed(this.authState.config.onAuthChange);\n }\n // Restart in case this refetch was triggered via schedule during\n // a reauthentication attempt.\n this._logVerbose(\n \"restarting WS after auth token fetch (if currently stopped)\",\n );\n this.tryRestartSocket();\n }\n\n private scheduleTokenRefetch(token: string) {\n if (this.authState.state === \"noAuth\") {\n return;\n }\n const decodedToken = this.decodeToken(token);\n if (!decodedToken) {\n // This is no longer really possible, because\n // we wait on server response before scheduling token refetch,\n // and the server currently requires JWT tokens.\n this.logger.error(\n \"Auth token is not a valid JWT, cannot refetch the token\",\n );\n return;\n }\n // iat: issued at time, UTC seconds timestamp at which the JWT was issued\n // exp: expiration time, UTC seconds timestamp at which the JWT will expire\n const { iat, exp } = decodedToken as { iat?: number; exp?: number };\n if (!iat || !exp) {\n this.logger.error(\n \"Auth token does not have required fields, cannot refetch the token\",\n );\n return;\n }\n // Because the client and server clocks may be out of sync,\n // we only know that the token will expire after `exp - iat`,\n // and since we just fetched a fresh one we know when that\n // will happen.\n const tokenValiditySeconds = exp - iat;\n if (tokenValiditySeconds <= 2) {\n this.logger.error(\n \"Auth token does not live long enough, cannot refetch the token\",\n );\n return;\n }\n // Attempt to refresh the token `refreshTokenLeewaySeconds` before it expires,\n // or immediately if the token is already expiring soon.\n let delay = Math.min(\n MAXIMUM_REFRESH_DELAY,\n (tokenValiditySeconds - this.refreshTokenLeewaySeconds) * 1000,\n );\n if (delay <= 0) {\n // Refetch immediately, but this might be due to configuring a `refreshTokenLeewaySeconds`\n // that is too large compared to the token's actual lifetime.\n this.logger.warn(\n `Refetching auth token immediately, configured leeway ${this.refreshTokenLeewaySeconds}s is larger than the token's lifetime ${tokenValiditySeconds}s`,\n );\n delay = 0;\n }\n const refetchTokenTimeoutId = setTimeout(() => {\n this._logVerbose(\"running scheduled token refetch\");\n void this.refetchToken();\n }, delay);\n this.setAuthState({\n state: \"waitingForScheduledRefetch\",\n refetchTokenTimeoutId,\n config: this.authState.config,\n });\n this._logVerbose(\n `scheduled preemptive auth token refetching in ${delay}ms`,\n );\n }\n\n // Protects against simultaneous calls to `setConfig`\n // while we're fetching a token\n private async fetchTokenAndGuardAgainstRace(\n fetchToken: AuthTokenFetcher,\n fetchArgs: {\n forceRefreshToken: boolean;\n },\n ) {\n const originalConfigVersion = ++this.configVersion;\n this._logVerbose(\n `fetching token with config version ${originalConfigVersion}`,\n );\n const token = await fetchToken(fetchArgs);\n if (this.configVersion !== originalConfigVersion) {\n // This is a stale config\n this._logVerbose(\n `stale config version, expected ${originalConfigVersion}, got ${this.configVersion}`,\n );\n return { isFromOutdatedConfig: true };\n }\n return { isFromOutdatedConfig: false, value: token };\n }\n\n stop() {\n this.resetAuthState();\n // Bump this in case we are mid-token-fetch when we get stopped\n this.configVersion++;\n this._logVerbose(`config version bumped to ${this.configVersion}`);\n }\n\n private setAndReportAuthFailed(\n onAuthChange: (authenticated: boolean) => void,\n ) {\n onAuthChange(false);\n this.resetAuthState();\n }\n\n private resetAuthState() {\n this.setAuthState({ state: \"noAuth\" });\n }\n\n private setAuthState(newAuth: AuthState) {\n const authStateForLog =\n newAuth.state === \"waitingForServerConfirmationOfFreshToken\"\n ? {\n hadAuth: newAuth.hadAuth,\n state: newAuth.state,\n token: `...${newAuth.token.slice(-7)}`,\n }\n : { state: newAuth.state };\n this._logVerbose(\n `setting auth state to ${JSON.stringify(authStateForLog)}`,\n );\n switch (newAuth.state) {\n case \"waitingForScheduledRefetch\":\n case \"notRefetching\":\n case \"noAuth\":\n this.tokenConfirmationAttempts = 0;\n break;\n case \"waitingForServerConfirmationOfFreshToken\":\n case \"waitingForServerConfirmationOfCachedToken\":\n case \"initialRefetch\":\n break;\n default: {\n newAuth satisfies never;\n }\n }\n if (this.authState.state === \"waitingForScheduledRefetch\") {\n // TODO: this side-effect would be better situated with scheduling refetch\n clearTimeout(this.authState.refetchTokenTimeoutId);\n }\n this.authState = newAuth;\n }\n\n private decodeToken(token: string) {\n try {\n return jwtDecode(token);\n } catch (e) {\n this._logVerbose(\n `Error decoding token: ${e instanceof Error ? e.message : \"Unknown error\"}`,\n );\n return null;\n }\n }\n\n private _logVerbose(message: string) {\n this.logger.logVerbose(`${message} [v${this.configVersion}]`);\n }\n}\n", "// Marks share a global namespace with other developer code.\nconst markNames = [\n \"convexClientConstructed\",\n \"convexWebSocketOpen\",\n \"convexFirstMessageReceived\",\n] as const;\nexport type MarkName = (typeof markNames)[number];\n\n// Mark details are not reported to the server.\ntype MarkDetail = {\n sessionId: string;\n};\n\n// `PerformanceMark`s are efficient and show up in browser's performance\n// timeline. They can be cleared with `performance.clearMarks()`.\n// This is a memory leak, but a worthwhile one: automatic\n// cleanup would make in-browser debugging more difficult.\nexport function mark(name: MarkName, sessionId: string) {\n const detail: MarkDetail = { sessionId };\n // `performance` APIs exists in browsers, Node.js, Deno, and more but it\n // is not required by the Convex client.\n if (typeof performance === \"undefined\" || !performance.mark) return;\n performance.mark(name, { detail });\n}\n\n// `PerfomanceMark` has a built-in toJSON() but the return type varies\n// between implementations, e.g. Node.js returns details but Chrome does not.\nfunction performanceMarkToJson(mark: PerformanceMark): MarkJson {\n // Remove \"convex\" prefix\n let name = mark.name.slice(\"convex\".length);\n // lowercase the first letter\n name = name.charAt(0).toLowerCase() + name.slice(1);\n return {\n name,\n startTime: mark.startTime,\n };\n}\n\n// Similar to the return type of `PerformanceMark.toJson()`.\nexport type MarkJson = {\n name: string;\n // `startTime` is in milliseconds since the time origin like `performance.now()`.\n // https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp#the_time_origin\n startTime: number;\n};\n\nexport function getMarksReport(sessionId: string): MarkJson[] {\n if (typeof performance === \"undefined\" || !performance.getEntriesByName) {\n return [];\n }\n const allMarks: PerformanceMark[] = [];\n for (const name of markNames) {\n const marks = (\n performance\n .getEntriesByName(name)\n .filter((entry) => entry.entryType === \"mark\") as PerformanceMark[]\n ).filter((mark) => mark.detail.sessionId === sessionId);\n allMarks.push(...marks);\n }\n return allMarks.map(performanceMarkToJson);\n}\n", "/**\n * BaseConvexClient should not be used directly and does not provide a stable\n * interface. It is a \"Base\" client not because it expects to be inherited from\n * but because other clients are built around it.\n *\n * BaseConvexClient is not Convex Function type-aware: it deals\n * with queries as functions that return Value, not the specific value.\n * Use a higher-level library to get types.\n */\nimport { version } from \"../../index.js\";\nimport { convexToJson, Value } from \"../../values/index.js\";\nimport {\n createHybridErrorStacktrace,\n forwardData,\n instantiateDefaultLogger,\n instantiateNoopLogger,\n logFatalError,\n Logger,\n} from \"../logging.js\";\nimport { LocalSyncState } from \"./local_state.js\";\nimport { RequestManager } from \"./request_manager.js\";\nimport {\n OptimisticLocalStore,\n OptimisticUpdate,\n} from \"./optimistic_updates.js\";\nimport {\n OptimisticQueryResults,\n QueryResultsMap,\n} from \"./optimistic_updates_impl.js\";\nimport {\n ActionRequest,\n MutationRequest,\n QueryId,\n QueryJournal,\n ServerMessage,\n RequestId,\n TS,\n UserIdentityAttributes,\n} from \"./protocol.js\";\nimport { RemoteQuerySet } from \"./remote_query_set.js\";\nimport { QueryToken, serializePathAndArgs } from \"./udf_path_utils.js\";\nimport { ReconnectMetadata, WebSocketManager } from \"./web_socket_manager.js\";\nimport { newSessionId } from \"./session.js\";\nimport { FunctionResult } from \"./function_result.js\";\nimport {\n AuthenticationManager,\n AuthTokenFetcher,\n} from \"./authentication_manager.js\";\nexport { type AuthTokenFetcher } from \"./authentication_manager.js\";\nimport { getMarksReport, mark, MarkName } from \"./metrics.js\";\nimport { parseArgs, validateDeploymentUrl } from \"../../common/index.js\";\nimport { ConvexError } from \"../../values/errors.js\";\nimport { jwtDecode } from \"../../vendor/jwt-decode/index.js\";\n\n/**\n * Options for {@link BaseConvexClient}.\n *\n * @public\n */\nexport interface BaseConvexClientOptions {\n /**\n * Whether to prompt the user if they have unsaved changes pending\n * when navigating away or closing a web page.\n *\n * This is only possible when the `window` object exists, i.e. in a browser.\n *\n * The default value is `true` in browsers.\n */\n unsavedChangesWarning?: boolean;\n /**\n * Specifies an alternate\n * [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)\n * constructor to use for client communication with the Convex cloud.\n * The default behavior is to use `WebSocket` from the global environment.\n */\n webSocketConstructor?: typeof WebSocket;\n /**\n * Adds additional logging for debugging purposes.\n *\n * The default value is `false`.\n */\n verbose?: boolean;\n /**\n * A logger, `true`, or `false`. If not provided or `true`, logs to the console.\n * If `false`, logs are not printed anywhere.\n *\n * You can construct your own logger to customize logging to log elsewhere.\n * A logger is an object with 4 methods: log(), warn(), error(), and logVerbose().\n * These methods can receive multiple arguments of any types, like console.log().\n */\n logger?: Logger | boolean;\n /**\n * Sends additional metrics to Convex for debugging purposes.\n *\n * The default value is `false`.\n */\n reportDebugInfoToConvex?: boolean;\n /**\n * This API is experimental: it may change or disappear.\n *\n * A function to call on receiving abnormal WebSocket close messages from the\n * connected Convex deployment. The content of these messages is not stable,\n * it is an implementation detail that may change.\n *\n * Consider this API an observability stopgap until higher level codes with\n * recommendations on what to do are available, which could be a more stable\n * interface instead of `string`.\n *\n * Check `connectionState` for more quantitative metrics about connection status.\n */\n onServerDisconnectError?: (message: string) => void;\n /**\n * Skip validating that the Convex deployment URL looks like\n * `https://happy-animal-123.convex.cloud` or localhost.\n *\n * This can be useful if running a self-hosted Convex backend that uses a different\n * URL.\n *\n * The default value is `false`\n */\n skipConvexDeploymentUrlCheck?: boolean;\n /**\n * If using auth, the number of seconds before a token expires that we should refresh it.\n *\n * The default value is `10`.\n */\n authRefreshTokenLeewaySeconds?: number;\n /**\n * This API is experimental: it may change or disappear.\n *\n * Whether query, mutation, and action requests should be held back\n * until the first auth token can be sent.\n *\n * Opting into this behavior works well for pages that should\n * only be viewed by authenticated clients.\n *\n * Defaults to false, not waiting for an auth token.\n */\n expectAuth?: boolean;\n}\n\n/**\n * State describing the client's connection with the Convex backend.\n *\n * @public\n */\nexport type ConnectionState = {\n hasInflightRequests: boolean;\n isWebSocketConnected: boolean;\n timeOfOldestInflightRequest: Date | null;\n /**\n * True if the client has ever opened a WebSocket to the \"ready\" state.\n */\n hasEverConnected: boolean;\n /**\n * The number of times this client has connected to the Convex backend.\n *\n * A number of things can cause the client to reconnect -- server errors,\n * bad internet, auth expiring. But this number being high is an indication\n * that the client is having trouble keeping a stable connection.\n */\n connectionCount: number;\n /**\n * The number of times this client has tried (and failed) to connect to the Convex backend.\n */\n connectionRetries: number;\n /**\n * The number of mutations currently in flight.\n */\n inflightMutations: number;\n /**\n * The number of actions currently in flight.\n */\n inflightActions: number;\n};\n\n/**\n * Options for {@link BaseConvexClient.subscribe}.\n *\n * @public\n */\nexport interface SubscribeOptions {\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 | undefined;\n}\n\n/**\n * Options for {@link BaseConvexClient.mutation}.\n *\n * @public\n */\nexport interface MutationOptions {\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<any> | undefined;\n}\n\n/**\n * Type describing updates to a query within a `Transition`.\n *\n * @public\n */\nexport type QueryModification =\n // `undefined` generally comes from an optimistic update setting the query to be loading\n { kind: \"Updated\"; result: FunctionResult | undefined } | { kind: \"Removed\" };\n\n/**\n * Object describing a transition passed into the `onTransition` handler.\n *\n * These can be from receiving a transition from the server, or from applying an\n * optimistic update locally.\n *\n * @public\n */\nexport type Transition = {\n queries: Array<{ token: QueryToken; modification: QueryModification }>;\n reflectedMutations: Array<{ requestId: RequestId; result: FunctionResult }>;\n timestamp: TS;\n};\n\n/**\n * Low-level client for directly integrating state management libraries\n * with Convex.\n *\n * Most developers should use higher level clients, like\n * the {@link ConvexHttpClient} or the React hook based {@link react.ConvexReactClient}.\n *\n * @public\n */\nexport class BaseConvexClient {\n private readonly address: string;\n private readonly state: LocalSyncState;\n private readonly requestManager: RequestManager;\n private readonly webSocketManager: WebSocketManager;\n private readonly authenticationManager: AuthenticationManager;\n private remoteQuerySet: RemoteQuerySet;\n private readonly optimisticQueryResults: OptimisticQueryResults;\n private _transitionHandlerCounter = 0;\n private _nextRequestId: RequestId;\n private _onTransitionFns: Map<number, (transition: Transition) => void> =\n new Map();\n private readonly _sessionId: string;\n private firstMessageReceived = false;\n private readonly debug: boolean;\n private readonly logger: Logger;\n private maxObservedTimestamp: TS | undefined;\n private connectionStateSubscribers = new Map<\n number,\n (connectionState: ConnectionState) => void\n >();\n private nextConnectionStateSubscriberId: number = 0;\n private _lastPublishedConnectionState: ConnectionState | 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 onTransition - A callback receiving an array of query tokens\n * corresponding to query results that have changed -- additional handlers\n * can be added via `addOnTransitionHandler`.\n * @param options - See {@link BaseConvexClientOptions} for a full description.\n */\n constructor(\n address: string,\n onTransition: (updatedQueries: QueryToken[]) => void,\n options?: BaseConvexClientOptions,\n ) {\n if (typeof address === \"object\") {\n throw new Error(\n \"Passing a ClientConfig object is no longer supported. Pass the URL of the Convex deployment as a string directly.\",\n );\n }\n if (options?.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n options = { ...options };\n const authRefreshTokenLeewaySeconds =\n options.authRefreshTokenLeewaySeconds ?? 10;\n let webSocketConstructor = options.webSocketConstructor;\n if (!webSocketConstructor && typeof WebSocket === \"undefined\") {\n throw new Error(\n \"No WebSocket global variable defined! To use Convex in an environment without WebSocket try the HTTP client: https://docs.convex.dev/api/classes/browser.ConvexHttpClient\",\n );\n }\n webSocketConstructor = webSocketConstructor || WebSocket;\n this.debug = options.reportDebugInfoToConvex ?? false;\n this.address = address;\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 // Substitute http(s) with ws(s)\n const i = address.search(\"://\");\n if (i === -1) {\n throw new Error(\"Provided address was not an absolute URL.\");\n }\n const origin = address.substring(i + 3); // move past the double slash\n const protocol = address.substring(0, i);\n let wsProtocol;\n if (protocol === \"http\") {\n wsProtocol = \"ws\";\n } else if (protocol === \"https\") {\n wsProtocol = \"wss\";\n } else {\n throw new Error(`Unknown parent protocol ${protocol}`);\n }\n const wsUri = `${wsProtocol}://${origin}/api/${version}/sync`;\n\n this.state = new LocalSyncState();\n this.remoteQuerySet = new RemoteQuerySet(\n (queryId) => this.state.queryPath(queryId),\n this.logger,\n );\n this.requestManager = new RequestManager(\n this.logger,\n this.markConnectionStateDirty,\n );\n\n // This is a callback for AuthenticationManager (which can't call\n // this synchronously, the callback wouldn't work) so the initial\n // pause for expectAuth we call it at the end of this constructor.\n const pauseSocket = () => {\n this.webSocketManager.pause();\n this.state.pause();\n };\n this.authenticationManager = new AuthenticationManager(\n this.state,\n {\n authenticate: (token) => {\n const message = this.state.setAuth(token);\n this.webSocketManager.sendMessage(message);\n return message.baseVersion;\n },\n stopSocket: () => this.webSocketManager.stop(),\n tryRestartSocket: () => this.webSocketManager.tryRestart(),\n pauseSocket,\n resumeSocket: () => this.webSocketManager.resume(),\n clearAuth: () => {\n this.clearAuth();\n },\n },\n {\n logger: this.logger,\n refreshTokenLeewaySeconds: authRefreshTokenLeewaySeconds,\n },\n );\n this.optimisticQueryResults = new OptimisticQueryResults();\n this.addOnTransitionHandler((transition) => {\n onTransition(transition.queries.map((q) => q.token));\n });\n this._nextRequestId = 0;\n this._sessionId = newSessionId();\n\n const { unsavedChangesWarning } = options;\n if (\n typeof window === \"undefined\" ||\n typeof window.addEventListener === \"undefined\"\n ) {\n if (unsavedChangesWarning === true) {\n throw new Error(\n \"unsavedChangesWarning requested, but window.addEventListener not found! Remove {unsavedChangesWarning: true} from Convex client options.\",\n );\n }\n } else if (unsavedChangesWarning !== false) {\n // Listen for tab close events and notify the user on unsaved changes.\n window.addEventListener(\"beforeunload\", (e) => {\n if (this.requestManager.hasIncompleteRequests()) {\n // There are 3 different ways to trigger this pop up so just try all of\n // them.\n\n e.preventDefault();\n // This confirmation message doesn't actually appear in most modern\n // browsers but we tried.\n const confirmationMessage =\n \"Are you sure you want to leave? Your changes may not be saved.\";\n // Recommended method for legacy (IE) browsers.\n // casts to avoid deprecation notices\n ((e || (window as any).event) as any).returnValue =\n confirmationMessage;\n return confirmationMessage;\n }\n });\n }\n\n this.webSocketManager = new WebSocketManager(\n wsUri,\n {\n onOpen: (reconnectMetadata: ReconnectMetadata) => {\n // We have a new WebSocket!\n this.mark(\"convexWebSocketOpen\");\n this.webSocketManager.sendMessage({\n ...reconnectMetadata,\n type: \"Connect\",\n sessionId: this._sessionId,\n maxObservedTimestamp: this.maxObservedTimestamp,\n });\n\n // Throw out our remote query, reissue queries\n // and outstanding mutations, and reauthenticate.\n this.remoteQuerySet = new RemoteQuerySet(\n (queryId) => this.state.queryPath(queryId),\n this.logger,\n );\n const [querySetModification, authModification] = this.state.restart();\n if (authModification) {\n this.webSocketManager.sendMessage(authModification);\n }\n this.webSocketManager.sendMessage(querySetModification);\n for (const message of this.requestManager.restart()) {\n this.webSocketManager.sendMessage(message);\n }\n },\n onResume: () => {\n const [querySetModification, authModification] = this.state.resume();\n if (authModification) {\n this.webSocketManager.sendMessage(authModification);\n }\n if (querySetModification) {\n this.webSocketManager.sendMessage(querySetModification);\n }\n for (const message of this.requestManager.resume()) {\n this.webSocketManager.sendMessage(message);\n }\n },\n onMessage: (serverMessage: ServerMessage) => {\n // Metrics events grow linearly with reconnection attempts so this\n // conditional prevents n^2 metrics reporting.\n if (!this.firstMessageReceived) {\n this.firstMessageReceived = true;\n this.mark(\"convexFirstMessageReceived\");\n this.reportMarks();\n }\n switch (serverMessage.type) {\n case \"Transition\": {\n this.observedTimestamp(serverMessage.endVersion.ts);\n this.authenticationManager.onTransition(serverMessage);\n this.remoteQuerySet.transition(serverMessage);\n this.state.transition(serverMessage);\n const completedRequests = this.requestManager.removeCompleted(\n this.remoteQuerySet.timestamp(),\n );\n this.notifyOnQueryResultChanges(completedRequests);\n break;\n }\n case \"MutationResponse\": {\n if (serverMessage.success) {\n this.observedTimestamp(serverMessage.ts);\n }\n const completedMutationInfo =\n this.requestManager.onResponse(serverMessage);\n if (completedMutationInfo !== null) {\n this.notifyOnQueryResultChanges(\n new Map([\n [\n completedMutationInfo.requestId,\n completedMutationInfo.result,\n ],\n ]),\n );\n }\n break;\n }\n case \"ActionResponse\": {\n this.requestManager.onResponse(serverMessage);\n break;\n }\n case \"AuthError\": {\n this.authenticationManager.onAuthError(serverMessage);\n break;\n }\n case \"FatalError\": {\n const error = logFatalError(this.logger, serverMessage.error);\n void this.webSocketManager.terminate();\n throw error;\n }\n default: {\n serverMessage satisfies never;\n }\n }\n\n return {\n hasSyncedPastLastReconnect: this.hasSyncedPastLastReconnect(),\n };\n },\n onServerDisconnectError: options.onServerDisconnectError,\n },\n webSocketConstructor,\n this.logger,\n this.markConnectionStateDirty,\n this.debug,\n );\n this.mark(\"convexClientConstructed\");\n\n // Begin client in a paused state waiting for an auth token.\n if (options.expectAuth) {\n pauseSocket();\n }\n }\n\n /**\n * Return true if there is outstanding work from prior to the time of the most recent restart.\n * This indicates that the client has not proven itself to have gotten past the issue that\n * potentially led to the restart. Use this to influence when to reset backoff after a failure.\n */\n private hasSyncedPastLastReconnect() {\n const hasSyncedPastLastReconnect =\n this.requestManager.hasSyncedPastLastReconnect() &&\n this.state.hasSyncedPastLastReconnect();\n return hasSyncedPastLastReconnect;\n }\n\n private observedTimestamp(observedTs: TS) {\n if (\n this.maxObservedTimestamp === undefined ||\n this.maxObservedTimestamp.lessThanOrEqual(observedTs)\n ) {\n this.maxObservedTimestamp = observedTs;\n }\n }\n\n getMaxObservedTimestamp() {\n return this.maxObservedTimestamp;\n }\n\n /**\n * Compute the current query results based on the remoteQuerySet and the\n * current optimistic updates and call `onTransition` for all the changed\n * queries.\n *\n * @param completedMutations - A set of mutation IDs whose optimistic updates\n * are no longer needed.\n */\n private notifyOnQueryResultChanges(\n completedRequests: Map<RequestId, FunctionResult>,\n ) {\n const remoteQueryResults: Map<QueryId, FunctionResult> =\n this.remoteQuerySet.remoteQueryResults();\n const queryTokenToValue: QueryResultsMap = new Map();\n for (const [queryId, result] of remoteQueryResults) {\n const queryToken = this.state.queryToken(queryId);\n // It's possible that we've already unsubscribed to this query but\n // the server hasn't learned about that yet. If so, ignore this one.\n\n if (queryToken !== null) {\n const query = {\n result,\n udfPath: this.state.queryPath(queryId)!,\n args: this.state.queryArgs(queryId)!,\n };\n queryTokenToValue.set(queryToken, query);\n }\n }\n\n // Query tokens that are new (because of new server results or new local optimistic updates)\n // or differ from old values (because of changes from local optimistic updates or new results\n // from the server).\n const changedQueryTokens =\n this.optimisticQueryResults.ingestQueryResultsFromServer(\n queryTokenToValue,\n new Set(completedRequests.keys()),\n );\n\n this.handleTransition({\n queries: changedQueryTokens.map((token) => {\n const optimisticResult =\n this.optimisticQueryResults.rawQueryResult(token);\n return {\n token,\n modification: {\n kind: \"Updated\" as const,\n result: optimisticResult,\n },\n };\n }),\n reflectedMutations: Array.from(completedRequests).map(\n ([requestId, result]) => ({\n requestId,\n result,\n }),\n ),\n timestamp: this.remoteQuerySet.timestamp(),\n });\n }\n\n private handleTransition(transition: Transition) {\n for (const fn of this._onTransitionFns.values()) {\n fn(transition);\n }\n }\n\n /**\n * Add a handler that will be called on a transition.\n *\n * Any external side effects (e.g. setting React state) should be handled here.\n *\n * @param fn\n *\n * @returns\n */\n addOnTransitionHandler(fn: (transition: Transition) => void) {\n const id = this._transitionHandlerCounter++;\n this._onTransitionFns.set(id, fn);\n return () => this._onTransitionFns.delete(id);\n }\n\n /**\n * Get the current JWT auth token and decoded claims.\n */\n getCurrentAuthClaims():\n | { token: string; decoded: Record<string, any> }\n | undefined {\n const authToken = this.state.getAuth();\n let decoded: Record<string, any> = {};\n if (authToken && authToken.tokenType === \"User\") {\n try {\n decoded = authToken ? jwtDecode(authToken.value) : {};\n } catch {\n decoded = {};\n }\n } else {\n return undefined;\n }\n return { token: authToken.value, decoded };\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 */\n setAuth(\n fetchToken: AuthTokenFetcher,\n onChange: (isAuthenticated: boolean) => void,\n ) {\n void this.authenticationManager.setConfig(fetchToken, onChange);\n }\n\n hasAuth() {\n return this.state.hasAuth();\n }\n\n /** @internal */\n setAdminAuth(value: string, fakeUserIdentity?: UserIdentityAttributes) {\n const message = this.state.setAdminAuth(value, fakeUserIdentity);\n this.webSocketManager.sendMessage(message);\n }\n\n clearAuth() {\n const message = this.state.clearAuth();\n this.webSocketManager.sendMessage(message);\n }\n\n /**\n * Subscribe to a query function.\n *\n * Whenever this query's result changes, the `onTransition` callback\n * passed into the constructor will be called.\n *\n * @param name - The name of the query.\n * @param args - An arguments object for the query. If this is omitted, the\n * arguments will be `{}`.\n * @param options - A {@link SubscribeOptions} options object for this query.\n\n * @returns An object containing a {@link QueryToken} corresponding to this\n * query and an `unsubscribe` callback.\n */\n subscribe(\n name: string,\n args?: Record<string, Value>,\n options?: SubscribeOptions,\n ): { queryToken: QueryToken; unsubscribe: () => void } {\n const argsObject = parseArgs(args);\n\n const { modification, queryToken, unsubscribe } = this.state.subscribe(\n name,\n argsObject,\n options?.journal,\n options?.componentPath,\n );\n if (modification !== null) {\n this.webSocketManager.sendMessage(modification);\n }\n return {\n queryToken,\n unsubscribe: () => {\n const modification = unsubscribe();\n if (modification) {\n this.webSocketManager.sendMessage(modification);\n }\n },\n };\n }\n\n /**\n * A query result based only on the current, local state.\n *\n * The only way this will return a value is if we're already subscribed to the\n * query or its value has been set optimistically.\n */\n localQueryResult(\n udfPath: string,\n args?: Record<string, Value>,\n ): Value | undefined {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(udfPath, argsObject);\n return this.optimisticQueryResults.queryResult(queryToken);\n }\n\n /**\n * Get query result by query token based on current, local state\n *\n * The only way this will return a value is if we're already subscribed to the\n * query or its value has been set optimistically.\n *\n * @internal\n */\n localQueryResultByToken(queryToken: QueryToken): Value | undefined {\n return this.optimisticQueryResults.queryResult(queryToken);\n }\n\n /**\n * Whether local query result is available for a token.\n *\n * This method does not throw if the result is an error.\n *\n * @internal\n */\n hasLocalQueryResultByToken(queryToken: QueryToken): boolean {\n return this.optimisticQueryResults.hasQueryResult(queryToken);\n }\n\n /**\n * @internal\n */\n localQueryLogs(\n udfPath: string,\n args?: Record<string, Value>,\n ): string[] | undefined {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(udfPath, argsObject);\n return this.optimisticQueryResults.queryLogs(queryToken);\n }\n\n /**\n * Retrieve the current {@link QueryJournal} for this query function.\n *\n * If we have not yet received a result for this query, this will be `undefined`.\n *\n * @param name - The name of the query.\n * @param args - The arguments object for this query.\n * @returns The query's {@link QueryJournal} or `undefined`.\n */\n queryJournal(\n name: string,\n args?: Record<string, Value>,\n ): QueryJournal | undefined {\n const argsObject = parseArgs(args);\n const queryToken = serializePathAndArgs(name, argsObject);\n return this.state.queryJournal(queryToken);\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 const wsConnectionState = this.webSocketManager.connectionState();\n return {\n hasInflightRequests: this.requestManager.hasInflightRequests(),\n isWebSocketConnected: wsConnectionState.isConnected,\n hasEverConnected: wsConnectionState.hasEverConnected,\n connectionCount: wsConnectionState.connectionCount,\n connectionRetries: wsConnectionState.connectionRetries,\n timeOfOldestInflightRequest:\n this.requestManager.timeOfOldestInflightRequest(),\n inflightMutations: this.requestManager.inflightMutations(),\n inflightActions: this.requestManager.inflightActions(),\n };\n }\n\n /**\n * Call this whenever the connection state may have changed in a way that could\n * require publishing it. Schedules a possibly update.\n */\n private markConnectionStateDirty = () => {\n void Promise.resolve().then(() => {\n const curConnectionState = this.connectionState();\n if (\n JSON.stringify(curConnectionState) !==\n JSON.stringify(this._lastPublishedConnectionState)\n ) {\n this._lastPublishedConnectionState = curConnectionState;\n for (const cb of this.connectionStateSubscribers.values()) {\n // One of these callback throwing will prevent other callbacks\n // from running but will not leave the client in a undefined state.\n cb(curConnectionState);\n }\n }\n });\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 *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(\n cb: (connectionState: ConnectionState) => void,\n ): () => void {\n const id = this.nextConnectionStateSubscriberId++;\n this.connectionStateSubscribers.set(id, cb);\n return () => {\n this.connectionStateSubscribers.delete(id);\n };\n }\n\n /**\n * Execute a mutation function.\n *\n * @param name - The name of the mutation.\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 this mutation.\n\n * @returns - A promise of the mutation's result.\n */\n async mutation(\n name: string,\n args?: Record<string, Value>,\n options?: MutationOptions,\n ): Promise<any> {\n const result = await this.mutationInternal(name, args, options);\n if (!result.success) {\n if (result.errorData !== undefined) {\n throw forwardData(\n result,\n new ConvexError(\n createHybridErrorStacktrace(\"mutation\", name, result),\n ),\n );\n }\n throw new Error(createHybridErrorStacktrace(\"mutation\", name, result));\n }\n return result.value;\n }\n\n /**\n * @internal\n */\n async mutationInternal(\n udfPath: string,\n args?: Record<string, Value>,\n options?: MutationOptions,\n componentPath?: string,\n ): Promise<FunctionResult> {\n const { mutationPromise } = this.enqueueMutation(\n udfPath,\n args,\n options,\n componentPath,\n );\n return mutationPromise;\n }\n\n /**\n * @internal\n */\n enqueueMutation(\n udfPath: string,\n args?: Record<string, Value>,\n options?: MutationOptions,\n componentPath?: string,\n ): { requestId: RequestId; mutationPromise: Promise<FunctionResult> } {\n const mutationArgs = parseArgs(args);\n this.tryReportLongDisconnect();\n const requestId = this.nextRequestId;\n this._nextRequestId++;\n\n if (options !== undefined) {\n const optimisticUpdate = options.optimisticUpdate;\n if (optimisticUpdate !== undefined) {\n const wrappedUpdate = (localQueryStore: OptimisticLocalStore) => {\n const result: unknown = optimisticUpdate(\n localQueryStore,\n mutationArgs,\n );\n if (result instanceof Promise) {\n this.logger.warn(\n \"Optimistic update handler returned a Promise. Optimistic updates should be synchronous.\",\n );\n }\n };\n\n const changedQueryTokens =\n this.optimisticQueryResults.applyOptimisticUpdate(\n wrappedUpdate,\n requestId,\n );\n\n const changedQueries = changedQueryTokens.map((token) => {\n const localResult = this.localQueryResultByToken(token);\n return {\n token,\n modification: {\n kind: \"Updated\" as const,\n result:\n localResult === undefined\n ? undefined\n : {\n success: true as const,\n value: localResult,\n logLines: [],\n },\n },\n };\n });\n this.handleTransition({\n queries: changedQueries,\n reflectedMutations: [],\n timestamp: this.remoteQuerySet.timestamp(),\n });\n }\n }\n\n const message: MutationRequest = {\n type: \"Mutation\",\n requestId,\n udfPath,\n componentPath,\n args: [convexToJson(mutationArgs)],\n };\n const mightBeSent = this.webSocketManager.sendMessage(message);\n const mutationPromise = this.requestManager.request(message, mightBeSent);\n return {\n requestId,\n mutationPromise,\n };\n }\n\n /**\n * Execute an action function.\n *\n * @param name - The name of the action.\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 async action(name: string, args?: Record<string, Value>): Promise<any> {\n const result = await this.actionInternal(name, args);\n if (!result.success) {\n if (result.errorData !== undefined) {\n throw forwardData(\n result,\n new ConvexError(createHybridErrorStacktrace(\"action\", name, result)),\n );\n }\n throw new Error(createHybridErrorStacktrace(\"action\", name, result));\n }\n return result.value;\n }\n\n /**\n * @internal\n */\n async actionInternal(\n udfPath: string,\n args?: Record<string, Value>,\n componentPath?: string,\n ): Promise<FunctionResult> {\n const actionArgs = parseArgs(args);\n const requestId = this.nextRequestId;\n this._nextRequestId++;\n this.tryReportLongDisconnect();\n\n const message: ActionRequest = {\n type: \"Action\",\n requestId,\n udfPath,\n componentPath,\n args: [convexToJson(actionArgs)],\n };\n\n const mightBeSent = this.webSocketManager.sendMessage(message);\n return this.requestManager.request(message, mightBeSent);\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 an {@link BaseConvexClient} 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.authenticationManager.stop();\n return this.webSocketManager.terminate();\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 * @internal\n */\n get nextRequestId() {\n return this._nextRequestId;\n }\n\n /**\n * @internal\n */\n get sessionId() {\n return this._sessionId;\n }\n\n // Instance property so that `mark()` doesn't need to be called as a method.\n private mark = (name: MarkName) => {\n if (this.debug) {\n mark(name, this.sessionId);\n }\n };\n\n /**\n * Reports performance marks to the server. This should only be called when\n * we have a functional websocket.\n */\n private reportMarks() {\n if (this.debug) {\n const report = getMarksReport(this.sessionId);\n this.webSocketManager.sendMessage({\n type: \"Event\",\n eventType: \"ClientConnect\",\n event: report,\n });\n }\n }\n\n private tryReportLongDisconnect() {\n if (!this.debug) {\n return;\n }\n const timeOfOldestRequest =\n this.connectionState().timeOfOldestInflightRequest;\n if (\n timeOfOldestRequest === null ||\n Date.now() - timeOfOldestRequest.getTime() <= 60 * 1000\n ) {\n return;\n }\n const endpoint = `${this.address}/api/debug_event`;\n fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n },\n body: JSON.stringify({ event: \"LongWebsocketDisconnect\" }),\n })\n .then((response) => {\n if (!response.ok) {\n this.logger.warn(\n \"Analytics request failed with response:\",\n response.body,\n );\n }\n })\n .catch((error) => {\n this.logger.warn(\"Analytics response failed with error:\", error);\n });\n }\n}\n", "import type { PaginationResult } from \"../../server/index.js\";\nimport type { Infer, Value } from \"../../values/index.js\";\nimport type { paginationOptsValidator } from \"../../server/index.js\";\n\nexport type PaginationStatus =\n | \"LoadingFirstPage\"\n | \"CanLoadMore\"\n | \"LoadingMore\"\n | \"Exhausted\";\n\nexport type PaginatedQueryResult<T> = {\n results: T[];\n status: PaginationStatus;\n loadMore: LoadMoreOfPaginatedQuery;\n};\n\n/**\n * Returns whether loading more was actually initiated; in cases where\n * a paginated query is already loading more items or there are no more\n * items available, calling loadMore() may do nothing.\n */\nexport type LoadMoreOfPaginatedQuery = (numItems: number) => boolean;\n\n// The arguments for each page query.\nexport function asPaginationArgs(value: Value): Record<string, Value> & {\n paginationOpts: Infer<typeof paginationOptsValidator>;\n} {\n if (typeof (value as any).paginationOpts.numItems !== \"number\") {\n throw new Error(`Not valid paginated query args: ${JSON.stringify(value)}`);\n }\n return value as unknown as Record<string, Value> & {\n paginationOpts: Infer<typeof paginationOptsValidator>;\n };\n}\n\n/**\n * Validates that a Value is a valid pagination result and returns it cast to PaginationResult.\n */\nexport function asPaginationResult(value: Value): PaginationResult<Value> {\n if (\n typeof value !== \"object\" ||\n value === null ||\n !Array.isArray((value as any).page) ||\n typeof (value as any).isDone !== \"boolean\" ||\n typeof (value as any).continueCursor !== \"string\"\n ) {\n throw new Error(`Not a valid paginated query result: ${value?.toString()}`);\n }\n return value as unknown as PaginationResult<Value>;\n}\n", "/**\n * PaginatedQueryClient maps subscriptions to paginated queries to the\n * individual page queries and handles page splits.\n *\n * In order to process all modified queries, paginated and normal, in the same\n * synchronous call the PaginatedQueryClient transition should be used exclusively.\n *\n * Like the BaseConvexClient, this client is not Convex Function type-aware: it deals\n * with queries as functions that return Value, not the specific value.\n * Use a higher-level library to get types.\n */\n\nimport { Value } from \"../../values/index.js\";\nimport {\n PaginatedQueryToken,\n QueryToken,\n serializePaginatedPathAndArgs,\n canonicalizeUdfPath,\n} from \"./udf_path_utils.js\";\nimport { BaseConvexClient, Transition } from \"./client.js\";\nimport {\n PaginatedQueryResult,\n PaginationStatus,\n asPaginationResult,\n} from \"./pagination.js\";\nimport { TS } from \"./protocol.js\";\nimport { Long } from \"../../vendor/long.js\";\n\ntype QueryPageKey = number;\n\n/**\n * Represents a paginated query subscription with multiple pages.\n *\n * To know the order of pages it's necessary to consult `pageKeys`.\n * The pages in this array are active, they constitute a gapless sequence of results.\n * Some pages are not in this array: they may be waiting for data for a page split.\n */\ntype LocalPaginatedQuery = {\n token: PaginatedQueryToken;\n canonicalizedUdfPath: string;\n args: Record<string, Value>; // WITHOUT paginationOpts\n numSubscribers: number;\n options: { initialNumItems: number };\n nextPageKey: QueryPageKey;\n pageKeys: QueryPageKey[]; // These pages make up the active page queries.\n // Map page keys to their query subscriptions\n pageKeyToQuery: Map<\n QueryPageKey,\n { queryToken: QueryToken; unsubscribe: () => void }\n >;\n ongoingSplits: Map<QueryPageKey, [QueryPageKey, QueryPageKey]>;\n skip: boolean;\n\n // Give separate uses of the query separate identities,\n // which may be removed in the future to improve caching.\n id: number;\n};\n\nexport interface SubscribeToPaginatedQueryOptions {\n initialNumItems: number;\n id: number;\n}\n\ntype AnyPaginatedQueryResult = PaginatedQueryResult<Value>;\n\nexport type PaginatedQueryModification =\n | { kind: \"Updated\"; result: AnyPaginatedQueryResult | undefined }\n | { kind: \"Removed\" };\n\nexport type ExtendedTransition = Transition & {\n paginatedQueries: Array<{\n token: PaginatedQueryToken;\n modification: PaginatedQueryModification;\n }>;\n};\n\nexport class PaginatedQueryClient {\n private paginatedQuerySet: Map<PaginatedQueryToken, LocalPaginatedQuery> =\n new Map();\n // hold onto a real Transition so we can construct synthetic ones with that timestamp\n private lastTransitionTs: TS;\n\n constructor(\n private client: BaseConvexClient,\n private onTransition: (transition: ExtendedTransition) => void,\n ) {\n // Nonsense initial value to construct synthetic Transitions\n this.lastTransitionTs = Long.fromNumber(0);\n this.client.addOnTransitionHandler((transition: Transition) =>\n this.onBaseTransition(transition),\n );\n }\n\n /**\n * Subscribe to a paginated query.\n *\n * @param name - The name of the paginated query function\n * @param args - Arguments for the query (excluding paginationOpts)\n * @param options - Pagination options including initialNumItems\n * @returns Object with paginatedQueryToken and unsubscribe function\n */\n subscribe(\n name: string,\n args: Record<string, Value>,\n options: SubscribeToPaginatedQueryOptions,\n ): {\n paginatedQueryToken: PaginatedQueryToken;\n unsubscribe: () => void;\n } {\n const canonicalizedUdfPath = canonicalizeUdfPath(name);\n // Note that only the expected options are included in the serialization.\n const token = serializePaginatedPathAndArgs(\n canonicalizedUdfPath,\n args,\n options,\n );\n\n const unsubscribe = () => this.removePaginatedQuerySubscriber(token);\n\n const existingEntry = this.paginatedQuerySet.get(token);\n if (existingEntry) {\n existingEntry.numSubscribers += 1;\n return {\n paginatedQueryToken: token,\n unsubscribe,\n };\n }\n\n // Create new paginated query\n this.paginatedQuerySet.set(token, {\n token,\n canonicalizedUdfPath,\n args,\n numSubscribers: 1,\n options: { initialNumItems: options.initialNumItems },\n nextPageKey: 0,\n pageKeys: [],\n pageKeyToQuery: new Map(),\n ongoingSplits: new Map(),\n skip: false,\n id: options.id,\n });\n\n this.addPageToPaginatedQuery(token, null, options.initialNumItems);\n\n return {\n paginatedQueryToken: token,\n unsubscribe,\n };\n }\n\n /**\n * Get current results for a paginated query based on local state.\n *\n * Throws an error when one of the pages has errored.\n */\n localQueryResult(\n name: string,\n args: Record<string, Value>,\n options: { initialNumItems: number; id: number },\n ): AnyPaginatedQueryResult | undefined {\n const canonicalizedUdfPath = canonicalizeUdfPath(name);\n const token = serializePaginatedPathAndArgs(\n canonicalizedUdfPath,\n args,\n options,\n );\n return this.localQueryResultByToken(token);\n }\n\n /**\n * @internal\n */\n localQueryResultByToken(\n token: PaginatedQueryToken,\n ): AnyPaginatedQueryResult | undefined {\n // undefined is probably the wrong value! Should be a real paginated query result for loading!\n // Butit's confusing why we'd ever get this, I guess some flows call localQueryResult before\n // subscribing? That's proabbly fair but is it consistent with the normal client?\n // What is the invariant here, will a token always exist? Or can a lookup occur at any time?\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n return undefined;\n }\n\n const activePages = this.activePageQueryTokens(paginatedQuery);\n if (activePages.length === 0) {\n return {\n results: [],\n status: \"LoadingFirstPage\",\n loadMore: (numItems: number) => {\n return this.loadMoreOfPaginatedQuery(token, numItems);\n },\n };\n }\n\n let allResults: Value[] = [];\n\n // Some page is loading (this isn't supposed to happen to any page but the last)\n let hasUndefined = false;\n let isDone = false;\n\n for (const pageToken of activePages) {\n // This throws, don't catch it, it should bubble up.\n // It might be a InvalidCursor Error. If it is, this query\n // should be reset (for now, use a new ID to ensure new state).\n //\n // In the future this might be caught and dealt with here but\n // an ID-based solution won't work here, ID is an intrinsic property\n // of this paginated query.\n const result = this.client.localQueryResultByToken(pageToken);\n\n if (result === undefined) {\n hasUndefined = true;\n isDone = false;\n continue;\n }\n\n const paginationResult = asPaginationResult(result);\n allResults = allResults.concat(paginationResult.page);\n // logic only relevant to the last page, we just happen to run it each time\n isDone = !!paginationResult.isDone;\n }\n\n let status: PaginationStatus;\n if (hasUndefined) {\n status = allResults.length === 0 ? \"LoadingFirstPage\" : \"LoadingMore\";\n } else if (isDone) {\n status = \"Exhausted\";\n } else {\n status = \"CanLoadMore\";\n }\n\n return {\n results: allResults,\n status,\n loadMore: (numItems: number) => {\n return this.loadMoreOfPaginatedQuery(token, numItems);\n },\n };\n }\n\n private onBaseTransition(transition: Transition) {\n const changedBaseTokens = transition.queries.map((q) => q.token);\n const changed = this.queriesContainingTokens(changedBaseTokens);\n\n let paginatedQueries: Array<{\n token: PaginatedQueryToken;\n modification: PaginatedQueryModification;\n }> = [];\n\n if (changed.length > 0) {\n this.processPaginatedQuerySplits(changed, (token) =>\n this.client.localQueryResultByToken(token),\n );\n\n paginatedQueries = changed.map((token) => ({\n token,\n modification: {\n kind: \"Updated\" as const,\n result: this.localQueryResultByToken(token),\n },\n }));\n }\n\n const extendedTransition: ExtendedTransition = {\n ...transition,\n paginatedQueries,\n };\n\n this.onTransition(extendedTransition);\n }\n\n /**\n * Load more items for a paginated query.\n *\n * This *always* causes a transition, the status of the query\n * has probably changed from \"CanLoadMore\" to \"LoadingMore\".\n * Data might have changed too: maybe a subscription to this page\n * query already exists (unlikely but possible) or this page query\n * has an optimistic update providing some initial data.\n *\n * @internal\n */\n private loadMoreOfPaginatedQuery(\n token: PaginatedQueryToken,\n numItems: number,\n ): boolean {\n this.mustGetPaginatedQuery(token);\n\n const lastPageToken = this.queryTokenForLastPageOfPaginatedQuery(token);\n const lastPageResult = this.client.localQueryResultByToken(lastPageToken);\n\n if (!lastPageResult) {\n // Still loading a page and concurrent loads are not allowed\n return false;\n }\n\n const paginationResult = asPaginationResult(lastPageResult);\n if (paginationResult.isDone) {\n // No more pages available\n return false;\n }\n\n this.addPageToPaginatedQuery(\n token,\n paginationResult.continueCursor,\n numItems,\n );\n\n const loadMoreTransition: ExtendedTransition = {\n timestamp: this.lastTransitionTs,\n reflectedMutations: [],\n queries: [],\n paginatedQueries: [\n {\n token,\n modification: {\n kind: \"Updated\" as const,\n result: this.localQueryResultByToken(token),\n },\n },\n ],\n };\n this.onTransition(loadMoreTransition);\n\n return true;\n }\n\n /**\n * @internal\n */\n private queriesContainingTokens(\n queryTokens: QueryToken[],\n ): PaginatedQueryToken[] {\n if (queryTokens.length === 0) {\n return [];\n }\n\n const changed: PaginatedQueryToken[] = [];\n const queryTokenSet = new Set(queryTokens);\n\n for (const [paginatedToken, paginatedQuery] of this.paginatedQuerySet) {\n for (const pageToken of this.allQueryTokens(paginatedQuery)) {\n if (queryTokenSet.has(pageToken)) {\n changed.push(paginatedToken);\n break;\n }\n }\n }\n\n return changed;\n }\n\n /**\n * @internal\n */\n private processPaginatedQuerySplits(\n changed: PaginatedQueryToken[],\n getResult: (token: QueryToken) => Value | undefined,\n ): void {\n for (const paginatedQueryToken of changed) {\n const paginatedQuery = this.mustGetPaginatedQuery(paginatedQueryToken);\n\n // These properties are all mutable, the destructure here is optional.\n const { ongoingSplits, pageKeyToQuery, pageKeys } = paginatedQuery;\n\n // Check for any completed splits\n for (const [pageKey, [splitKey1, splitKey2]] of ongoingSplits) {\n const bothNewPagesLoaded =\n getResult(pageKeyToQuery.get(splitKey1)!.queryToken) !== undefined &&\n getResult(pageKeyToQuery.get(splitKey2)!.queryToken) !== undefined;\n\n if (bothNewPagesLoaded) {\n this.completePaginatedQuerySplit(\n paginatedQuery,\n pageKey,\n splitKey1,\n splitKey2,\n );\n }\n }\n\n // Check each active page for splits needed\n for (const pageKey of pageKeys) {\n if (ongoingSplits.has(pageKey)) {\n continue; // Already splitting\n }\n\n const pageToken = pageKeyToQuery.get(pageKey)!.queryToken;\n const pageResult = getResult(pageToken);\n if (!pageResult) {\n continue;\n }\n const result = asPaginationResult(pageResult);\n\n // Check if this page needs splitting\n const shouldSplit =\n result.splitCursor &&\n (result.pageStatus === \"SplitRecommended\" ||\n result.pageStatus === \"SplitRequired\" ||\n // This client-driven page splitting condition will change in the future.\n result.page.length > paginatedQuery.options.initialNumItems * 2);\n\n if (shouldSplit) {\n this.splitPaginatedQueryPage(\n paginatedQuery,\n pageKey,\n result.splitCursor!, // we just checked\n result.continueCursor,\n );\n }\n }\n }\n }\n\n private splitPaginatedQueryPage(\n paginatedQuery: LocalPaginatedQuery,\n pageKey: QueryPageKey,\n splitCursor: string,\n continueCursor: string | null,\n ): void {\n const splitKey1 = paginatedQuery.nextPageKey++;\n const splitKey2 = paginatedQuery.nextPageKey++;\n\n const paginationOpts: Value = {\n cursor: continueCursor,\n numItems: paginatedQuery.options.initialNumItems,\n id: paginatedQuery.id,\n };\n\n // First split page: same cursor as original, but add endCursor at splitCursor\n const firstSubscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n {\n ...paginatedQuery.args,\n paginationOpts: {\n ...paginationOpts,\n cursor: null, // Start from beginning for first split\n endCursor: splitCursor,\n },\n },\n );\n paginatedQuery.pageKeyToQuery.set(splitKey1, firstSubscription);\n\n // Second split page: cursor starts at splitCursor, endCursor is the original continueCursor\n const secondSubscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n {\n ...paginatedQuery.args,\n paginationOpts: {\n ...paginationOpts,\n cursor: splitCursor,\n endCursor: continueCursor,\n },\n },\n );\n paginatedQuery.pageKeyToQuery.set(splitKey2, secondSubscription);\n\n paginatedQuery.ongoingSplits.set(pageKey, [splitKey1, splitKey2]);\n }\n\n /**\n * @internal\n */\n private addPageToPaginatedQuery(\n token: PaginatedQueryToken,\n continueCursor: string | null,\n numItems: number,\n ): { queryToken: QueryToken; unsubscribe: () => void } {\n const paginatedQuery = this.mustGetPaginatedQuery(token);\n const pageKey = paginatedQuery.nextPageKey++;\n\n const paginationOpts: Value = {\n cursor: continueCursor,\n numItems,\n id: paginatedQuery.id,\n };\n\n const pageArgs = {\n ...paginatedQuery.args,\n paginationOpts,\n };\n\n const subscription = this.client.subscribe(\n paginatedQuery.canonicalizedUdfPath,\n pageArgs,\n );\n\n paginatedQuery.pageKeys.push(pageKey);\n paginatedQuery.pageKeyToQuery.set(pageKey, subscription);\n return subscription;\n }\n\n private removePaginatedQuerySubscriber(token: PaginatedQueryToken): void {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n return;\n }\n\n paginatedQuery.numSubscribers -= 1;\n if (paginatedQuery.numSubscribers > 0) {\n return;\n }\n\n // Remove all page subscriptions by calling their unsubscribe callbacks\n for (const subscription of paginatedQuery.pageKeyToQuery.values()) {\n subscription.unsubscribe();\n }\n\n this.paginatedQuerySet.delete(token);\n }\n\n private completePaginatedQuerySplit(\n paginatedQuery: LocalPaginatedQuery,\n pageKey: QueryPageKey,\n splitKey1: QueryPageKey,\n splitKey2: QueryPageKey,\n ): void {\n const originalQuery = paginatedQuery.pageKeyToQuery.get(pageKey)!;\n paginatedQuery.pageKeyToQuery.delete(pageKey);\n const pageIndex = paginatedQuery.pageKeys.indexOf(pageKey);\n paginatedQuery.pageKeys.splice(pageIndex, 1, splitKey1, splitKey2);\n paginatedQuery.ongoingSplits.delete(pageKey);\n originalQuery.unsubscribe();\n }\n\n /** The query tokens for all active pages, in result order */\n private activePageQueryTokens(\n paginatedQuery: LocalPaginatedQuery,\n ): QueryToken[] {\n return paginatedQuery.pageKeys.map(\n (pageKey) => paginatedQuery.pageKeyToQuery.get(pageKey)!.queryToken,\n );\n }\n\n private allQueryTokens(paginatedQuery: LocalPaginatedQuery): QueryToken[] {\n return Array.from(paginatedQuery.pageKeyToQuery.values()).map(\n (sub) => sub.queryToken,\n );\n }\n\n private queryTokenForLastPageOfPaginatedQuery(\n token: PaginatedQueryToken,\n ): QueryToken {\n const paginatedQuery = this.mustGetPaginatedQuery(token);\n const lastPageKey =\n paginatedQuery.pageKeys[paginatedQuery.pageKeys.length - 1];\n if (lastPageKey === undefined) {\n throw new Error(`No pages for paginated query ${token}`);\n }\n return paginatedQuery.pageKeyToQuery.get(lastPageKey)!.queryToken;\n }\n\n private mustGetPaginatedQuery(\n token: PaginatedQueryToken,\n ): LocalPaginatedQuery {\n const paginatedQuery = this.paginatedQuerySet.get(token);\n if (!paginatedQuery) {\n throw new Error(\"paginated query no longer exists for token \" + token);\n }\n return paginatedQuery;\n }\n}\n", "import { validateDeploymentUrl } from \"../common/index.js\";\nimport {\n BaseConvexClient,\n BaseConvexClientOptions,\n MutationOptions,\n PaginatedQueryToken,\n QueryToken,\n UserIdentityAttributes,\n} from \"./index.js\";\nimport {\n FunctionArgs,\n FunctionReference,\n FunctionReturnType,\n PaginationResult,\n} from \"../server/index.js\";\nimport { getFunctionName } from \"../server/api.js\";\nimport { AuthTokenFetcher } from \"./sync/authentication_manager.js\";\nimport { ConnectionState } from \"./sync/client.js\";\nimport {\n ExtendedTransition,\n PaginatedQueryClient,\n} from \"./sync/paginated_query_client.js\";\nimport { PaginatedQueryResult } from \"./sync/pagination.js\";\nimport { serializedQueryTokenIsPaginated } from \"./sync/udf_path_utils.js\";\n\n// In Node.js builds this points to a bundled WebSocket implementation. If no\n// WebSocket implementation is manually specified or globally available,\n// this one is used.\nlet defaultWebSocketConstructor: typeof WebSocket | undefined;\n\n/** internal */\nexport function setDefaultWebSocketConstructor(ws: typeof WebSocket) {\n defaultWebSocketConstructor = ws;\n}\n\nexport type ConvexClientOptions = BaseConvexClientOptions & {\n /**\n * `disabled` makes onUpdate callback registration a no-op and actions,\n * mutations and one-shot queries throw. Setting disabled to true may be\n * useful for server-side rendering, where subscriptions don't make sense.\n */\n disabled?: boolean;\n /**\n * Whether to prompt users in browsers about queued or in-flight mutations.\n * This only works in environments where `window.onbeforeunload` is available.\n *\n * Defaults to true when `window` is defined, otherwise false.\n */\n unsavedChangesWarning?: boolean;\n};\n\n/**\n * Stops callbacks from running.\n *\n * @public\n */\nexport type Unsubscribe<T> = {\n /** Stop calling callback when query results changes. If this is the last listener on this query, stop received updates. */\n (): void;\n /** Stop calling callback when query results changes. If this is the last listener on this query, stop received updates. */\n unsubscribe(): void;\n /** Get the last known value, possibly with local optimistic updates applied. */\n getCurrentValue(): T | undefined;\n /** @internal */\n getQueryLogs(): string[] | undefined;\n};\n\n/**\n * Subscribes to Convex query functions and executes mutations and actions over a WebSocket.\n *\n * Optimistic updates for mutations are not provided for this client.\n * Third party clients may choose to wrap {@link browser.BaseConvexClient} for additional control.\n *\n * ```ts\n * const client = new ConvexClient(\"https://happy-otter-123.convex.cloud\");\n * const unsubscribe = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages[0].body);\n * });\n * ```\n *\n * @public\n */\nexport class ConvexClient {\n private listeners: Set<QueryInfo>;\n private _client: BaseConvexClient | undefined;\n private _paginatedClient: PaginatedQueryClient | undefined;\n // A synthetic server event to run callbacks the first time\n private callNewListenersWithCurrentValuesTimer:\n | ReturnType<typeof setTimeout>\n | undefined;\n private _closed: boolean;\n private _disabled: boolean;\n /**\n * Once closed no registered callbacks will fire again.\n */\n get closed(): boolean {\n return this._closed;\n }\n get client(): BaseConvexClient {\n if (this._client) return this._client;\n throw new Error(\"ConvexClient is disabled\");\n }\n /**\n * @internal\n */\n get paginatedClient(): PaginatedQueryClient {\n if (this._paginatedClient) return this._paginatedClient;\n throw new Error(\"ConvexClient is disabled\");\n }\n get disabled(): boolean {\n return this._disabled;\n }\n\n /**\n * Construct a client and immediately initiate a WebSocket connection to the passed address.\n *\n * @public\n */\n constructor(address: string, options: ConvexClientOptions = {}) {\n if (options.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n const { disabled, ...baseOptions } = options;\n this._closed = false;\n this._disabled = !!disabled;\n if (\n defaultWebSocketConstructor &&\n !(\"webSocketConstructor\" in baseOptions) &&\n typeof WebSocket === \"undefined\"\n ) {\n baseOptions.webSocketConstructor = defaultWebSocketConstructor;\n }\n if (\n typeof window === \"undefined\" &&\n !(\"unsavedChangesWarning\" in baseOptions)\n ) {\n baseOptions.unsavedChangesWarning = false;\n }\n if (!this.disabled) {\n this._client = new BaseConvexClient(\n address,\n () => {}, // NOP, let the paginated query client do it all\n baseOptions,\n );\n this._paginatedClient = new PaginatedQueryClient(\n this._client,\n (transition) => this._transition(transition),\n );\n }\n this.listeners = new Set();\n }\n\n /**\n * Call a callback whenever a new result for a query is received. The callback\n * will run soon after being registered if a result for the query is already\n * in memory.\n *\n * The return value is an {@link Unsubscribe} object which is both a function\n * an an object with properties. Both of the patterns below work with this object:\n *\n *```ts\n * // call the return value as a function\n * const unsubscribe = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages);\n * });\n * unsubscribe();\n *\n * // unpack the return value into its properties\n * const {\n * getCurrentValue,\n * unsubscribe,\n * } = client.onUpdate(api.messages.list, {}, (messages) => {\n * console.log(messages);\n * });\n *```\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - The arguments to run the query with.\n * @param callback - Function to call when the query result updates.\n * @param onError - Function to call when the query result updates with an error.\n * If not provided, errors will be thrown instead of calling the callback.\n *\n * @return an {@link Unsubscribe} function to stop calling the onUpdate function.\n */\n onUpdate<Query extends FunctionReference<\"query\">>(\n query: Query,\n args: FunctionArgs<Query>,\n callback: (result: FunctionReturnType<Query>) => unknown,\n onError?: (e: Error) => unknown,\n ): Unsubscribe<Query[\"_returnType\"]> {\n if (this.disabled) {\n return this.createDisabledUnsubscribe<Query[\"_returnType\"]>();\n }\n\n // BaseConvexClient takes care of deduplicating queries subscriptions...\n const { queryToken, unsubscribe } = this.client.subscribe(\n getFunctionName(query),\n args,\n );\n\n // ...but we still need to bookkeep callbacks to actually call them.\n const queryInfo: QueryInfo = {\n queryToken,\n callback,\n onError,\n unsubscribe,\n hasEverRun: false,\n query,\n args,\n paginationOptions: undefined,\n };\n this.listeners.add(queryInfo);\n\n // If the callback is registered for a query with a result immediately available\n // schedule a fake transition to call the callback soon instead of waiting for\n // a new server update (which could take seconds or days).\n if (\n this.queryResultReady(queryToken) &&\n this.callNewListenersWithCurrentValuesTimer === undefined\n ) {\n this.callNewListenersWithCurrentValuesTimer = setTimeout(\n () => this.callNewListenersWithCurrentValues(),\n 0,\n );\n }\n\n const unsubscribeProps: RemoveCallSignature<\n Unsubscribe<Query[\"_returnType\"]>\n > = {\n unsubscribe: () => {\n if (this.closed) {\n // all unsubscribes already ran\n return;\n }\n this.listeners.delete(queryInfo);\n unsubscribe();\n },\n getCurrentValue: () => this.client.localQueryResultByToken(queryToken),\n getQueryLogs: () => this.client.localQueryLogs(queryToken),\n };\n const ret = unsubscribeProps.unsubscribe as Unsubscribe<\n Query[\"_returnType\"]\n >;\n Object.assign(ret, unsubscribeProps);\n return ret;\n }\n\n /**\n * Call a callback whenever a new result for a paginated query is received.\n *\n * This is an experimental preview: the final API may change.\n * In particular, caching behavior, page splitting, and required paginated query options\n * may change.\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - The arguments to run the query with.\n * @param options - Options for the paginated query including initialNumItems and id.\n * @param callback - Function to call when the query result updates.\n * @param onError - Function to call when the query result updates with an error.\n *\n * @return an {@link Unsubscribe} function to stop calling the callback.\n */\n onPaginatedUpdate_experimental<Query extends FunctionReference<\"query\">>(\n query: Query,\n args: FunctionArgs<Query>,\n options: { initialNumItems: number },\n callback: (result: PaginationResult<FunctionReturnType<Query>>) => unknown,\n onError?: (e: Error) => unknown,\n ): Unsubscribe<PaginatedQueryResult<FunctionReturnType<Query>[]>> {\n if (this.disabled) {\n return this.createDisabledUnsubscribe<\n PaginatedQueryResult<FunctionReturnType<Query>>\n >();\n }\n\n const paginationOptions = {\n initialNumItems: options.initialNumItems,\n id: -1,\n };\n\n const { paginatedQueryToken, unsubscribe } = this.paginatedClient.subscribe(\n getFunctionName(query),\n args,\n // Simple client doesn't use IDs, there's no expectation that these queries remain separate.\n paginationOptions,\n );\n\n const queryInfo: QueryInfo = {\n queryToken: paginatedQueryToken,\n callback,\n onError,\n unsubscribe,\n hasEverRun: false,\n query,\n args,\n paginationOptions,\n };\n this.listeners.add(queryInfo);\n\n // If the callback is registered for a query with a result immediately available\n // schedule a fake transition to call the callback soon instead of waiting for\n // a new server update (which could take seconds or days).\n if (\n !!this.paginatedClient.localQueryResultByToken(paginatedQueryToken) &&\n this.callNewListenersWithCurrentValuesTimer === undefined\n ) {\n this.callNewListenersWithCurrentValuesTimer = setTimeout(\n () => this.callNewListenersWithCurrentValues(),\n 0,\n );\n }\n\n const unsubscribeProps: RemoveCallSignature<\n Unsubscribe<PaginatedQueryResult<FunctionReturnType<Query>[]>>\n > = {\n unsubscribe: () => {\n if (this.closed) {\n // all unsubscribes already ran\n return;\n }\n this.listeners.delete(queryInfo);\n unsubscribe();\n },\n getCurrentValue: () => {\n const result = this.paginatedClient.localQueryResult(\n getFunctionName(query),\n args,\n paginationOptions,\n );\n // cast to apply the specific function type\n return result as\n | PaginatedQueryResult<FunctionReturnType<Query>>\n | undefined;\n },\n getQueryLogs: () => [], // Paginated queries don't aggregate their logs\n };\n const ret = unsubscribeProps.unsubscribe as Unsubscribe<\n PaginatedQueryResult<FunctionReturnType<Query>>\n >;\n Object.assign(ret, unsubscribeProps);\n return ret;\n }\n\n // Run all callbacks that have never been run before if they have a query\n // result available now.\n private callNewListenersWithCurrentValues() {\n this.callNewListenersWithCurrentValuesTimer = undefined;\n this._transition({ queries: [], paginatedQueries: [] }, true);\n }\n\n private queryResultReady(queryToken: QueryToken): boolean {\n return this.client.hasLocalQueryResultByToken(queryToken);\n }\n\n private createDisabledUnsubscribe<T>(): Unsubscribe<T> {\n const disabledUnsubscribe = (() => {}) as Unsubscribe<T>;\n const unsubscribeProps: RemoveCallSignature<Unsubscribe<T>> = {\n unsubscribe: disabledUnsubscribe,\n getCurrentValue: () => undefined,\n getQueryLogs: () => undefined,\n };\n Object.assign(disabledUnsubscribe, unsubscribeProps);\n return disabledUnsubscribe;\n }\n\n async close() {\n if (this.disabled) return;\n // prevent pending updates\n this.listeners.clear();\n this._closed = true;\n if (this._paginatedClient) {\n this._paginatedClient = undefined;\n }\n return this.client.close();\n }\n\n /**\n * Get the current JWT auth token and decoded claims.\n */\n getAuth(): { token: string; decoded: Record<string, any> } | undefined {\n if (this.disabled) return;\n return this.client.getCurrentAuthClaims();\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 (typically an OpenID Connect Identity Token)\n * @param onChange - a callback that will be called when the authentication status changes\n */\n setAuth(\n fetchToken: AuthTokenFetcher,\n onChange?: (isAuthenticated: boolean) => void,\n ) {\n if (this.disabled) return;\n this.client.setAuth(\n fetchToken,\n onChange ??\n (() => {\n // Do nothing\n }),\n );\n }\n\n /**\n * @internal\n */\n setAdminAuth(token: string, identity?: UserIdentityAttributes) {\n if (this.closed) {\n throw new Error(\"ConvexClient has already been closed.\");\n }\n if (this.disabled) return;\n this.client.setAdminAuth(token, identity);\n }\n\n /**\n * @internal\n */\n _transition(\n {\n queries,\n paginatedQueries,\n }: Pick<ExtendedTransition, \"queries\" | \"paginatedQueries\">,\n callNewListeners = false,\n ) {\n const updatedQueries = [\n ...queries.map((q) => q.token),\n ...paginatedQueries.map((q) => q.token),\n ];\n\n // Deduping subscriptions happens in the BaseConvexClient, so not much to do here.\n\n // Call all callbacks in the order they were registered\n for (const queryInfo of this.listeners) {\n const { callback, queryToken, onError, hasEverRun } = queryInfo;\n const isPaginatedQuery = serializedQueryTokenIsPaginated(queryToken);\n\n // What does it mean to have a paginated query result ready? I think it's\n // always going to fire immediately.\n const hasResultReady = isPaginatedQuery\n ? !!this.paginatedClient.localQueryResultByToken(queryToken)\n : this.client.hasLocalQueryResultByToken(queryToken);\n\n if (\n updatedQueries.includes(queryToken) ||\n (callNewListeners && !hasEverRun && hasResultReady)\n ) {\n queryInfo.hasEverRun = true;\n let newValue;\n try {\n if (isPaginatedQuery) {\n newValue = this.paginatedClient.localQueryResultByToken(queryToken);\n } else {\n newValue = this.client.localQueryResultByToken(queryToken);\n }\n } catch (error) {\n if (!(error instanceof Error)) throw error;\n if (onError) {\n onError(\n error,\n \"Second argument to onUpdate onError is reserved for later use\",\n );\n } else {\n // Make some noise without unsubscribing or failing to call other callbacks.\n void Promise.reject(error);\n }\n continue;\n }\n callback(\n newValue,\n \"Second argument to onUpdate callback is reserved for later use\",\n );\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.\n * @param options - A {@link MutationOptions} options object for the mutation.\n * @returns A promise of the mutation's result.\n */\n async mutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n args: FunctionArgs<Mutation>,\n options?: MutationOptions,\n ): Promise<Awaited<FunctionReturnType<Mutation>>> {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return await this.client.mutation(getFunctionName(mutation), 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.\n * @returns A promise of the action's result.\n */\n async action<Action extends FunctionReference<\"action\">>(\n action: Action,\n args: FunctionArgs<Action>,\n ): Promise<Awaited<FunctionReturnType<Action>>> {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return await this.client.action(getFunctionName(action), args);\n }\n\n /**\n * Fetch a query result once.\n *\n * @param query - A {@link server.FunctionReference} for the public query\n * to run.\n * @param args - An arguments object for the query.\n * @returns A promise of the query's result.\n */\n async query<Query extends FunctionReference<\"query\">>(\n query: Query,\n args: Query[\"_args\"],\n ): Promise<Awaited<Query[\"_returnType\"]>> {\n if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n const value = this.client.localQueryResult(getFunctionName(query), args) as\n | Awaited<Query[\"_returnType\"]>\n | undefined;\n if (value !== undefined) return Promise.resolve(value);\n\n return new Promise((resolve, reject) => {\n const { unsubscribe } = this.onUpdate(\n query,\n args,\n (value) => {\n unsubscribe();\n resolve(value);\n },\n (e: Error) => {\n unsubscribe();\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 if (this.disabled) throw new Error(\"ConvexClient is disabled\");\n return this.client.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 *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(\n cb: (connectionState: ConnectionState) => void,\n ): () => void {\n if (this.disabled) return () => {};\n return this.client.subscribeToConnectionState(cb);\n }\n}\n\n// internal information tracked about each registered callback\ntype QueryInfo = {\n callback: (result: any, meta: unknown) => unknown;\n onError: ((e: Error, meta: unknown) => unknown) | undefined;\n unsubscribe: () => void;\n queryToken: QueryToken | PaginatedQueryToken;\n hasEverRun: boolean;\n // query, args and paginationOptions are just here for debugging, the queryToken is authoritative\n query: FunctionReference<\"query\">;\n args: any;\n paginationOptions: { initialNumItems: number; id: number } | undefined;\n};\n\n// helps to construct objects with a call signature\ntype RemoveCallSignature<T> = Omit<T, never>;\n", "import {\n FunctionReference,\n FunctionReturnType,\n OptionalRestArgs,\n getFunctionName,\n} from \"../server/api.js\";\nimport { parseArgs, validateDeploymentUrl } from \"../common/index.js\";\nimport { version } from \"../index.js\";\nimport {\n ConvexError,\n JSONValue,\n convexToJson,\n jsonToConvex,\n} from \"../values/index.js\";\nimport {\n instantiateDefaultLogger,\n instantiateNoopLogger,\n logForFunction,\n Logger,\n} from \"./logging.js\";\nimport {\n ArgsAndOptions,\n FunctionArgs,\n UserIdentityAttributes,\n} from \"../server/index.js\";\n\nexport const STATUS_CODE_OK = 200;\nexport const STATUS_CODE_BAD_REQUEST = 400;\n// Special custom 5xx HTTP status code to mean that the UDF returned an error.\n//\n// Must match the constant of the same name in the backend.\nexport const STATUS_CODE_UDF_FAILED = 560;\n\n// Allow fetch to be shimmed in for Node.js < 18\nlet specifiedFetch: typeof globalThis.fetch | undefined = undefined;\nexport function setFetch(f: typeof globalThis.fetch) {\n specifiedFetch = f;\n}\n\nexport type HttpMutationOptions = {\n /**\n * Skip the default queue of mutations and run this immediately.\n *\n * This allows the same HttpConvexClient to be used to request multiple\n * mutations in parallel, something not possible with WebSocket-based clients.\n */\n skipQueue: boolean;\n};\n\n/**\n * A Convex client that runs queries and mutations over HTTP.\n *\n * This client is stateful (it has user credentials and queues mutations)\n * so take care to avoid sharing it between requests in a server.\n *\n * This is appropriate for server-side code (like Netlify Lambdas) or non-reactive\n * webapps.\n *\n * @public\n */\nexport class ConvexHttpClient {\n private readonly address: string;\n private auth: string | undefined;\n private adminAuth: string | undefined;\n private encodedTsPromise?: Promise<string>;\n private debug: boolean;\n private fetchOptions?: FetchOptions;\n private fetch?: typeof globalThis.fetch | undefined;\n private logger: Logger;\n private mutationQueue: Array<{\n mutation: FunctionReference<\"mutation\">;\n args: FunctionArgs<any>;\n resolve: (value: any) => void;\n reject: (error: any) => void;\n }> = [];\n private isProcessingQueue: boolean = false;\n\n /**\n * Create a new {@link ConvexHttpClient}.\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 - An object of options.\n * - `skipConvexDeploymentUrlCheck` - Skip validating that the Convex deployment URL looks like\n * `https://happy-animal-123.convex.cloud` or localhost. This can be useful if running a self-hosted\n * Convex backend that uses a different URL.\n * - `logger` - A logger or a boolean. If not provided, logs to the console.\n * You can construct your own logger to customize logging to log elsewhere\n * or not log at all, or use `false` as a shorthand for a no-op logger.\n * A logger is an object with 4 methods: log(), warn(), error(), and logVerbose().\n * These methods can receive multiple arguments of any types, like console.log().\n * - `auth` - A JWT containing identity claims accessible in Convex functions.\n * This identity may expire so it may be necessary to call `setAuth()` later,\n * but for short-lived clients it's convenient to specify this value here.\n * - `fetch` - A custom fetch implementation to use for all HTTP requests made by this client.\n */\n constructor(\n address: string,\n options?: {\n skipConvexDeploymentUrlCheck?: boolean;\n logger?: Logger | boolean;\n auth?: string;\n fetch?: typeof globalThis.fetch;\n },\n ) {\n if (typeof options === \"boolean\") {\n throw new Error(\n \"skipConvexDeploymentUrlCheck as the second argument is no longer supported. Please pass an options object, `{ skipConvexDeploymentUrlCheck: true }`.\",\n );\n }\n const opts = options ?? {};\n if (opts.skipConvexDeploymentUrlCheck !== true) {\n validateDeploymentUrl(address);\n }\n this.logger =\n options?.logger === false\n ? instantiateNoopLogger({ verbose: false })\n : options?.logger !== true && options?.logger\n ? options.logger\n : instantiateDefaultLogger({ verbose: false });\n this.address = address;\n this.debug = true;\n this.auth = undefined;\n this.adminAuth = undefined;\n this.fetch = options?.fetch;\n if (options?.auth) {\n this.setAuth(options.auth);\n }\n }\n\n /**\n * Obtain the {@link ConvexHttpClient}'s URL to its backend.\n * @deprecated Use url, which returns the url without /api at the end.\n *\n * @returns The URL to the Convex backend, including the client's API version.\n */\n backendUrl(): string {\n return `${this.address}/api`;\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 * Set the authentication token to be used for subsequent queries and mutations.\n *\n * Should be called whenever the token changes (i.e. due to expiration and refresh).\n *\n * @param value - JWT-encoded OpenID Connect identity token.\n */\n setAuth(value: string) {\n this.clearAuth();\n this.auth = value;\n }\n\n /**\n * Set admin auth token to allow calling internal queries, mutations, and actions\n * and acting as an identity.\n *\n * @internal\n */\n setAdminAuth(token: string, actingAsIdentity?: UserIdentityAttributes) {\n this.clearAuth();\n if (actingAsIdentity !== undefined) {\n // Encode the identity to a base64 string\n const bytes = new TextEncoder().encode(JSON.stringify(actingAsIdentity));\n const actingAsIdentityEncoded = btoa(String.fromCodePoint(...bytes));\n this.adminAuth = `${token}:${actingAsIdentityEncoded}`;\n } else {\n this.adminAuth = token;\n }\n }\n\n /**\n * Clear the current authentication token if set.\n */\n clearAuth() {\n this.auth = undefined;\n this.adminAuth = undefined;\n }\n\n /**\n * Sets whether the result log lines should be printed on the console or not.\n *\n * @internal\n */\n setDebug(debug: boolean) {\n this.debug = debug;\n }\n\n /**\n * Used to customize the fetch behavior in some runtimes.\n *\n * @internal\n */\n setFetchOptions(fetchOptions: FetchOptions) {\n this.fetchOptions = fetchOptions;\n }\n\n /**\n * This API is experimental: it may change or disappear.\n *\n * Execute a Convex query function at the same timestamp as every other\n * consistent query execution run by this HTTP client.\n *\n * This doesn't make sense for long-lived ConvexHttpClients as Convex\n * backends can read a limited amount into the past: beyond 30 seconds\n * in the past may not be available.\n *\n * Create a new client to use a consistent time.\n *\n * @param name - The name of the query.\n * @param args - The 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 * @deprecated This API is experimental: it may change or disappear.\n */\n async consistentQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgs<Query>\n ): Promise<FunctionReturnType<Query>> {\n const queryArgs = parseArgs(args[0]);\n\n const timestampPromise = this.getTimestamp();\n return await this.queryInner(query, queryArgs, { timestampPromise });\n }\n\n private async getTimestamp() {\n if (this.encodedTsPromise) {\n return this.encodedTsPromise;\n }\n return (this.encodedTsPromise = this.getTimestampInner());\n }\n\n private async getTimestampInner() {\n const localFetch = this.fetch || specifiedFetch || fetch;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n const response = await localFetch(`${this.address}/api/query_ts`, {\n ...this.fetchOptions,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok) {\n throw new Error(await response.text());\n }\n const { ts } = (await response.json()) as { ts: string };\n return ts;\n }\n\n /**\n * Execute a Convex query function.\n *\n * @param name - The name of the query.\n * @param args - The 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 async query<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgs<Query>\n ): Promise<FunctionReturnType<Query>> {\n const queryArgs = parseArgs(args[0]);\n return await this.queryInner(query, queryArgs, {});\n }\n\n private async queryInner<Query extends FunctionReference<\"query\">>(\n query: Query,\n queryArgs: FunctionArgs<Query>,\n options: { timestampPromise?: Promise<string> },\n ): Promise<FunctionReturnType<Query>> {\n const name = getFunctionName(query);\n const args = [convexToJson(queryArgs)];\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n if (this.adminAuth) {\n headers[\"Authorization\"] = `Convex ${this.adminAuth}`;\n } else if (this.auth) {\n headers[\"Authorization\"] = `Bearer ${this.auth}`;\n }\n const localFetch = this.fetch || specifiedFetch || fetch;\n\n const timestamp = options.timestampPromise\n ? await options.timestampPromise\n : undefined;\n\n const body = JSON.stringify({\n path: name,\n format: \"convex_encoded_json\",\n args,\n ...(timestamp ? { ts: timestamp } : {}),\n });\n const endpoint = timestamp\n ? `${this.address}/api/query_at_ts`\n : `${this.address}/api/query`;\n\n const response = await localFetch(endpoint, {\n ...this.fetchOptions,\n body,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {\n throw new Error(await response.text());\n }\n const respJSON = await response.json();\n\n if (this.debug) {\n for (const line of respJSON.logLines ?? []) {\n logForFunction(this.logger, \"info\", \"query\", name, line);\n }\n }\n switch (respJSON.status) {\n case \"success\":\n return jsonToConvex(respJSON.value);\n case \"error\":\n if (respJSON.errorData !== undefined) {\n throw forwardErrorData(\n respJSON.errorData,\n new ConvexError(respJSON.errorMessage),\n );\n }\n throw new Error(respJSON.errorMessage);\n default:\n throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);\n }\n }\n\n private async mutationInner<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n mutationArgs: FunctionArgs<Mutation>,\n ): Promise<FunctionReturnType<Mutation>> {\n const name = getFunctionName(mutation);\n const body = JSON.stringify({\n path: name,\n format: \"convex_encoded_json\",\n args: [convexToJson(mutationArgs)],\n });\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n if (this.adminAuth) {\n headers[\"Authorization\"] = `Convex ${this.adminAuth}`;\n } else if (this.auth) {\n headers[\"Authorization\"] = `Bearer ${this.auth}`;\n }\n const localFetch = this.fetch || specifiedFetch || fetch;\n const response = await localFetch(`${this.address}/api/mutation`, {\n ...this.fetchOptions,\n body,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {\n throw new Error(await response.text());\n }\n const respJSON = await response.json();\n if (this.debug) {\n for (const line of respJSON.logLines ?? []) {\n logForFunction(this.logger, \"info\", \"mutation\", name, line);\n }\n }\n switch (respJSON.status) {\n case \"success\":\n return jsonToConvex(respJSON.value);\n case \"error\":\n if (respJSON.errorData !== undefined) {\n throw forwardErrorData(\n respJSON.errorData,\n new ConvexError(respJSON.errorMessage),\n );\n }\n throw new Error(respJSON.errorMessage);\n default:\n throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);\n }\n }\n\n private async processMutationQueue() {\n if (this.isProcessingQueue) {\n return;\n }\n\n this.isProcessingQueue = true;\n while (this.mutationQueue.length > 0) {\n const { mutation, args, resolve, reject } = this.mutationQueue.shift()!;\n try {\n const result = await this.mutationInner(mutation, args);\n resolve(result);\n } catch (error) {\n reject(error);\n }\n }\n this.isProcessingQueue = false;\n }\n\n private enqueueMutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n args: FunctionArgs<Mutation>,\n ): Promise<FunctionReturnType<Mutation>> {\n return new Promise((resolve, reject) => {\n this.mutationQueue.push({ mutation, args, resolve, reject });\n void this.processMutationQueue();\n });\n }\n\n /**\n * Execute a Convex mutation function. Mutations are queued by default.\n *\n * @param name - The name of the mutation.\n * @param args - The arguments object for the mutation. If this is omitted,\n * the arguments will be `{}`.\n * @param options - An optional object containing\n * @returns A promise of the mutation's result.\n */\n async mutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n ...args: ArgsAndOptions<Mutation, HttpMutationOptions>\n ): Promise<FunctionReturnType<Mutation>> {\n const [fnArgs, options] = args;\n const mutationArgs = parseArgs(fnArgs);\n const queued = !options?.skipQueue;\n\n if (queued) {\n return await this.enqueueMutation(mutation, mutationArgs);\n } else {\n return await this.mutationInner(mutation, mutationArgs);\n }\n }\n\n /**\n * Execute a Convex action function. Actions are not queued.\n *\n * @param name - The name of the action.\n * @param args - The 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 async action<Action extends FunctionReference<\"action\">>(\n action: Action,\n ...args: OptionalRestArgs<Action>\n ): Promise<FunctionReturnType<Action>> {\n const actionArgs = parseArgs(args[0]);\n const name = getFunctionName(action);\n const body = JSON.stringify({\n path: name,\n format: \"convex_encoded_json\",\n args: [convexToJson(actionArgs)],\n });\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n if (this.adminAuth) {\n headers[\"Authorization\"] = `Convex ${this.adminAuth}`;\n } else if (this.auth) {\n headers[\"Authorization\"] = `Bearer ${this.auth}`;\n }\n const localFetch = this.fetch || specifiedFetch || fetch;\n const response = await localFetch(`${this.address}/api/action`, {\n ...this.fetchOptions,\n body,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {\n throw new Error(await response.text());\n }\n const respJSON = await response.json();\n if (this.debug) {\n for (const line of respJSON.logLines ?? []) {\n logForFunction(this.logger, \"info\", \"action\", name, line);\n }\n }\n switch (respJSON.status) {\n case \"success\":\n return jsonToConvex(respJSON.value);\n case \"error\":\n if (respJSON.errorData !== undefined) {\n throw forwardErrorData(\n respJSON.errorData,\n new ConvexError(respJSON.errorMessage),\n );\n }\n throw new Error(respJSON.errorMessage);\n default:\n throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);\n }\n }\n\n /**\n * Execute a Convex function of an unknown type. These function calls are not queued.\n *\n * @param name - The name of the function.\n * @param args - The arguments object for the function. If this is omitted,\n * the arguments will be `{}`.\n * @returns A promise of the function's result.\n *\n * @internal\n */\n async function<\n AnyFunction extends FunctionReference<\"query\" | \"mutation\" | \"action\">,\n >(\n anyFunction: AnyFunction | string,\n componentPath?: string,\n ...args: OptionalRestArgs<AnyFunction>\n ): Promise<FunctionReturnType<AnyFunction>> {\n const functionArgs = parseArgs(args[0]);\n const name =\n typeof anyFunction === \"string\"\n ? anyFunction\n : getFunctionName(anyFunction);\n const body = JSON.stringify({\n componentPath: componentPath,\n path: name,\n format: \"convex_encoded_json\",\n args: convexToJson(functionArgs),\n });\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Convex-Client\": `npm-${version}`,\n };\n if (this.adminAuth) {\n headers[\"Authorization\"] = `Convex ${this.adminAuth}`;\n } else if (this.auth) {\n headers[\"Authorization\"] = `Bearer ${this.auth}`;\n }\n const localFetch = this.fetch || specifiedFetch || fetch;\n const response = await localFetch(`${this.address}/api/function`, {\n ...this.fetchOptions,\n body,\n method: \"POST\",\n headers: headers,\n });\n if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {\n throw new Error(await response.text());\n }\n const respJSON = await response.json();\n if (this.debug) {\n for (const line of respJSON.logLines ?? []) {\n logForFunction(this.logger, \"info\", \"any\", name, line);\n }\n }\n switch (respJSON.status) {\n case \"success\":\n return jsonToConvex(respJSON.value);\n case \"error\":\n if (respJSON.errorData !== undefined) {\n throw forwardErrorData(\n respJSON.errorData,\n new ConvexError(respJSON.errorMessage),\n );\n }\n throw new Error(respJSON.errorMessage);\n default:\n throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);\n }\n }\n}\n\nfunction forwardErrorData(errorData: JSONValue, error: ConvexError<string>) {\n (error as ConvexError<any>).data = jsonToConvex(errorData);\n return error;\n}\n\n/**\n * @internal\n */\ntype FetchOptions = { cache: \"force-cache\" | \"no-store\" };\n", "// Inspired by https://tanstack.com/query/v5/docs/framework/react/guides/query-options\nimport type { FunctionArgs, FunctionReference } from \"../server/api.js\";\n\n/**\n * Options for a Convex query: the query function reference and its arguments.\n *\n * Used with the object-form overload of {@link useQuery}.\n *\n * @public\n */\nexport type QueryOptions<Query extends FunctionReference<\"query\">> = {\n /**\n * The query function to run.\n */\n query: Query;\n /**\n * The arguments to the query function.\n */\n args: FunctionArgs<Query>;\n};\n\n/**\n * Creates a type-safe {@link QueryOptions} object for a Convex query.\n *\n * This is an identity function that exists to provide type inference \u2014 passing\n * your query and args through this helper ensures TypeScript infers the correct\n * `Query` type parameter, which enables precise return types on hooks like\n * {@link useQuery}.\n *\n * ```typescript\n * const opts = convexQueryOptions({\n * query: api.users.getById,\n * args: { id: userId },\n * });\n * // opts is typed as QueryOptions<typeof api.users.getById>\n * client.prewarmQuery(opts);\n * ```\n *\n * @param options - The query and its arguments.\n * @returns The same object, typed as `QueryOptions<Query>`.\n * @internal\n */\nexport function convexQueryOptions<Query extends FunctionReference<\"query\">>(\n options: QueryOptions<Query>,\n): QueryOptions<Query> {\n return options;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["value", "functionName", "version", "code", "mark", "modification", "value"]
|
|
7
7
|
}
|