RJ
RJ
CCConvex Community
Created by RJ on 12/9/2024 in #support-community
Fuzzy search for function names in functions panel
Would be nice 🙂 I also always assume that it works like this and only remember after my fuzzy query fails.
29 replies
CCConvex Community
Created by RJ on 10/18/2024 in #support-community
Schema validation succeeds when adding a non-optional field to a union variant
Let's say I have a table like this:
defineSchema({
my_table: defineTable(v.union(
v.object({
tag: v.literal("A"),
}),
v.object({
tag: v.literal("B"),
})
))
})
defineSchema({
my_table: defineTable(v.union(
v.object({
tag: v.literal("A"),
}),
v.object({
tag: v.literal("B"),
})
))
})
Which contains some documents, like these:
[{ tag: "A" }, { tag: "B" }]
[{ tag: "A" }, { tag: "B" }]
If I add a new (non-optional) field to one of the variants:
defineSchema({
my_table: defineTable(v.union(
v.object({
tag: v.literal("A"),
+ a_field: v.string()
}),
v.object({
tag: v.literal("B"),
})
))
})
defineSchema({
my_table: defineTable(v.union(
v.object({
tag: v.literal("A"),
+ a_field: v.string()
}),
v.object({
tag: v.literal("B"),
})
))
})
Schema validation succeeds, thus permitting invalid documents in that table. Validation seems to work correctly in other contexts (e.g. insertion, patching).
12 replies
CCConvex Community
Created by RJ on 10/7/2024 in #support-community
Document ID length
It looks from the source code like document IDs must be between 31 and 37 characters—is that correct? What are the odds that this ever changes?
6 replies
CCConvex Community
Created by RJ on 9/5/2024 in #support-community
Serializing/deserializing `Request`/`Response` objects in HTTP action
I'm trying to integrate Effect's HTTP API library (it's like Hono, basically) with my Convex HTTP API, but (until someone adds a Convex platform for @effect/platform 🙂) doing so requires me to run the HTTP endpoint handlers in a Node runtime. I'm at the point where I have a function (request: Request) => Response, but if I can't run the handler directly in the HTTP action, maybe I could serialize/deserialize the Request/Response objects? I'm curious whether this has come up before, and (either way) whether anyone has any knowledge of whether this is possible/feasible, either in the general case or in certain narrower ones.
24 replies
CCConvex Community
Created by RJ on 7/21/2024 in #support-community
`db.patch` accepts optional `_id` and `_creationTime` parameters
Is this expected?
8 replies
CCConvex Community
Created by RJ on 7/15/2024 in #support-community
Nested optional search field type error
Given a schema that looks like this:
documents: defineTable({
fieldOne: v.string(),
fieldTwo: v.optional(v.object({
subFieldOne: v.string(),
})),
}).searchIndex("search_field_two", {
searchField: "fieldOne",
filterFields: ["fieldTwo.subFieldOne"],
}),
documents: defineTable({
fieldOne: v.string(),
fieldTwo: v.optional(v.object({
subFieldOne: v.string(),
})),
}).searchIndex("search_field_two", {
searchField: "fieldOne",
filterFields: ["fieldTwo.subFieldOne"],
}),
The following query produces a type error:
const data = await ctx.db
.query("documents")
.withSearchIndex("search_field_two", (q) =>
q
.search("fieldOne", "string")
.eq(
"fieldTwo.subFieldOne",
"string"
// ^ Argument of type '"string"' is not assignable to parameter of type 'undefined'.
)
)
.collect();
const data = await ctx.db
.query("documents")
.withSearchIndex("search_field_two", (q) =>
q
.search("fieldOne", "string")
.eq(
"fieldTwo.subFieldOne",
"string"
// ^ Argument of type '"string"' is not assignable to parameter of type 'undefined'.
)
)
.collect();
Repro: - GH repo: https://github.com/rjdellecese/nested-optional-search-filter-field-test - Offending line: https://github.com/rjdellecese/nested-optional-search-filter-field-test/blob/04dd3545aa0e83ed6deac84b186b6e64e43d4c59/convex/myFunctions.ts#L83
8 replies
CCConvex Community
Created by RJ on 7/11/2024 in #support-community
Difference between union of true & false vs boolean validators?
I recently wrote a ValueToValidator type which converts a Convex Value into its corresponding Convex Validator. It was quite tricky to write, but it's now almost entirely functional, save one small inconsistency.
type Boolean = ValueToValidator<boolean>
// ✅ VBoolean<boolean, "required">

type UnionOfBooleanLiterals = ValueToValidator<true | false>
// 🟡 VBoolean<boolean, "required">

type UnionIncludingBoolean = ValueToValidator<string | boolean>
// 🟡 VUnion<string | boolean, [
// VLiteral<false, "required">,
// VLiteral<true, "required">,
// VString<string, "required">
// ], "required", never>
type Boolean = ValueToValidator<boolean>
// ✅ VBoolean<boolean, "required">

type UnionOfBooleanLiterals = ValueToValidator<true | false>
// 🟡 VBoolean<boolean, "required">

type UnionIncludingBoolean = ValueToValidator<string | boolean>
// 🟡 VUnion<string | boolean, [
// VLiteral<false, "required">,
// VLiteral<true, "required">,
// VString<string, "required">
// ], "required", never>
I don't think that the boolean type and true | false type literals are distinguishable (but if you think I'm wrong about that please let me know), so I think the best I could probably do is ensure that true | false is always translated to VBoolean<boolean, "required">. But that got me thinking—how does Convex represent this at lower-levels? I assume boolean ultimately becomes true | false, but was curious to verify. Also, should VBoolean<boolean, "required"> (somehow) reduce to VUnion<boolean, [VLiteral<true, "required">, VLiteral<false, "required">]>?
1 replies
CCConvex Community
Created by RJ on 6/14/2024 in #support-community
Reactive queries firing after Clerk sign-out
I've noticed for a while that when a user logs out of my application (say by clicking a Clerk "Sign out" button), reactive queries which they were subscribed to at the time execute before the parent component which checks for auth is re-rendered, but without UserIdentity data, meaning that such queries then throw an error. I'm using the <AuthLoading>, <Unauthenticated />, and <Authenticated> helpers, but this nonetheless occurs in reactive queries that are children of <Authenticated>. Is this at all a known issue? Or any ideas about why this might be occurring/how to fix it?
7 replies
CCConvex Community
Created by RJ on 4/30/2024 in #support-community
Unable to execute internal action from dashboard or CLI
I've got an internal action which I use to invite users to my application. It accepts some parameters (emailAddress and userRole) and coordinates with Clerk to send an invitation email and add the user to the DB with the correct role. It was intended to be run exclusively from the dashboard (or the CLI via convex run, though the dashboard is generally much easier). However, I'm running into some odd issues attempting to execute it by either method. See attached screen recording for what happens when I try to execute it via the dashboard. When I try to execute it via the CLI, I'm getting a validation error that I'm not sure I believe (scrubbed of some irrelevant data/PII):
$ pnpm doppler run --command="pnpm convex run --prod scripts/operational/inviteUser '{
\"emailAddress\": \"name@website.com\",
\"userRole\": { \"tag\": \"BrandPartner\", \"brandPartnerId\": \"xxx\" }
}'"
Using DOPPLER_CONFIG_DIR from the environment. To disable this, use --no-read-env.
✖ Failed to run function "scripts/operational/inviteUser":
Error: [Request ID: a802de57bfc6abaa] Server Error
ArgumentValidationError: Value does not match validator.
Path: .userRole
Value: {brandPartnerId: "xxx", tag: "BrandPartner"}
Validator: v.union(v.object({tag: v.literal("Internal")}), v.object({brandPartnerId: v.id("brandPartners"), tag: v.literal("BrandPartner")}), v.object({relationships: v.array(v.object({brandPartnerId: v.id("brandPartners"), retailer: v.union(...)})), tag: v.literal("SalesRep")}))
$ pnpm doppler run --command="pnpm convex run --prod scripts/operational/inviteUser '{
\"emailAddress\": \"name@website.com\",
\"userRole\": { \"tag\": \"BrandPartner\", \"brandPartnerId\": \"xxx\" }
}'"
Using DOPPLER_CONFIG_DIR from the environment. To disable this, use --no-read-env.
✖ Failed to run function "scripts/operational/inviteUser":
Error: [Request ID: a802de57bfc6abaa] Server Error
ArgumentValidationError: Value does not match validator.
Path: .userRole
Value: {brandPartnerId: "xxx", tag: "BrandPartner"}
Validator: v.union(v.object({tag: v.literal("Internal")}), v.object({brandPartnerId: v.id("brandPartners"), tag: v.literal("BrandPartner")}), v.object({relationships: v.array(v.object({brandPartnerId: v.id("brandPartners"), retailer: v.union(...)})), tag: v.literal("SalesRep")}))
12 replies
CCConvex Community
Created by RJ on 4/17/2024 in #support-community
Transient error while executing action
I was testing something which involved recursive action execution (run an action, then run it again with scheduler.runAfter(0, ...), until the base case is reached), and I ran into a failure which was logged as Transient error while executing action. What is this? Should I expect it to happen regularly? Do I need to orchestrate some state management/retry scaffolding in order to anticipate the possibility of this occurring?
3 replies
CCConvex Community
Created by RJ on 3/3/2024 in #support-community
`"use node";` in HTTP actions
I just used sharp (https://github.com/lovell/sharp) to build an HTTP action which accepts a storage ID and a desired width and height (as search params), and returns a dynamically-sized image. The HTTP action works pretty well, but since sharp needs to be bundled as an external package, it only works in the Node runtime, which isn't available for HTTP actions. So I have to instead call out to another, separate action, which does the actual transforming, and then do some munging to get the image encoded as a base64 string (in order to return it to the HTTP action), and then returned as a proper image in the HTTP action's response (which means, I think, that it needs to become a Blob once more). My questions: 1. Why don't HTTP actions support the Node environment? Could they? 2. Given the current limitations, any suggestions for how I might improve this setup?
2 replies
CCConvex Community
Created by RJ on 3/1/2024 in #support-community
Minor visual bug in docs search
2 replies
CCConvex Community
Created by RJ on 2/20/2024 in #support-community
Filter by documents with fields which are equal to a set (>= 2) of values using an index?
Say I have a table that looks like this:
books: defineTable({
author: v.string(),
content: v.string(),
}).index("by_author", ["author"])
books: defineTable({
author: v.string(),
content: v.string(),
}).index("by_author", ["author"])
and I'd like to retrieve a collection of documents belonging to the authors "Stendhal" and "Alexandre Dumas". If I use .filter, I understand that this is achievable in one query:
db.query("books")
.filter((q) =>
q.or(
q.eq(q.field("author"), "Stendhal"),
q.eq(q.field("author"), "Alexandre Dumas"),
)
)
.collect()
db.query("books")
.filter((q) =>
q.or(
q.eq(q.field("author"), "Stendhal"),
q.eq(q.field("author"), "Alexandre Dumas"),
)
)
.collect()
but is it possible to achieve in one query using an index?
db.query("books")
.withIndex(
"by_author",
(q) => q.eq("author", "Stendhal")
// * No `q.or` available
// * Further chaining with
// q.eq(...).eq(...) doesn't work,
// according to the types
// * Neither may additional indexes be used
)
db.query("books")
.withIndex(
"by_author",
(q) => q.eq("author", "Stendhal")
// * No `q.or` available
// * Further chaining with
// q.eq(...).eq(...) doesn't work,
// according to the types
// * Neither may additional indexes be used
)
5 replies
CCConvex Community
Created by RJ on 2/7/2024 in #support-community
Deprecated `ActionCtx` used in `httpActionGeneric`
I've gotten back to work on my Convex/Effect library and discovered that httpActionGeneric (https://docs.convex.dev/api/modules/server#httpactiongeneric) is using the deprecated ActionCtx (https://docs.convex.dev/api/interfaces/server.ActionCtx) rather than (what I assume should be) GenericActionCtx (https://docs.convex.dev/api/interfaces/server.GenericActionCtx), which is causing me some type issues.
2 replies
CCConvex Community
Created by RJ on 1/17/2024 in #support-community
Vercel Error: 500: INTERNAL_SERVER_ERROR
No description
14 replies
CCConvex Community
Created by RJ on 1/8/2024 in #support-community
`"ExpiredInQueue"`, `"Too many concurrent requests…"`
I'm receiving the following error in one of my actions, and am having trouble understanding why.
{"code":"ExpiredInQueue","message":"Too many concurrent requests, backoff and try again."}
{"code":"ExpiredInQueue","message":"Too many concurrent requests, backoff and try again."}
This is occurring in an action (called extractProductListings) which is doing a few different things, including executing http requests, mutations and queries, but it is limited to performing only a max of 10 of these concurrently. However, extractProductListings is being executed by another action, which is executing extractProductListings many times concurrently. These all comprise a scraping script, which is intended to perform a lot of computation (web requests, queries, and mutations) simultaneously in a short period of time. I've tried to be mindful of conforming to the limits described here (https://docs.convex.dev/functions/actions#limits), and believe I am conforming to them, so I'm wondering if there could be some constraints not described in the docs that I'm running into. Is it the case, for example, that there are global concurrency limits (per Convex account) which I'm encountering? Or perhaps there's something else I might not be considering?
31 replies
CCConvex Community
Created by RJ on 12/14/2023 in #support-community
`Cannot find module 'rollup/parseAst' or its corresponding type declarations.`
I just upgraded from Convex 1.5.1 to 1.6.3 and I'm now getting the following error when running convex dev:
✖ TypeScript typecheck via `tsc` failed.
To ignore failing typecheck, use `--typecheck=disable`.
- Collecting TypeScript errors

node_modules/vite/dist/node/index.d.ts:6:41 - error TS2307: Cannot find module 'rollup/parseAst' or its corresponding type declarations.

6 export { parseAst, parseAstAsync } from 'rollup/parseAst';
~~~~~~~~~~~~~~~~~

Found 1 error in node_modules/vite/dist/node/index.d.ts:6
✖ TypeScript typecheck via `tsc` failed.
To ignore failing typecheck, use `--typecheck=disable`.
- Collecting TypeScript errors

node_modules/vite/dist/node/index.d.ts:6:41 - error TS2307: Cannot find module 'rollup/parseAst' or its corresponding type declarations.

6 export { parseAst, parseAstAsync } from 'rollup/parseAst';
~~~~~~~~~~~~~~~~~

Found 1 error in node_modules/vite/dist/node/index.d.ts:6
Any clue why this might be/how to resolve it?
18 replies
CCConvex Community
Created by RJ on 11/16/2023 in #support-community
User impersonation with Clerk
I'm implementing user impersonation with Clerk (https://clerk.com/docs/custom-flows/user-impersonation), and appear to have succeed in creating an actor token through Clerk's API and authenticating with it. My ostensible proof of this:
import { useAuth } from "@clerk/clerk-react";

// ...

const { actor } = useAuth(); // `actor` is present
import { useAuth } from "@clerk/clerk-react";

// ...

const { actor } = useAuth(); // `actor` is present
My understanding, per https://clerk.com/docs/custom-flows/user-impersonation#jwt-claims, is when impersonating a user, the sub claim should contain the ID for the impersonated user, so Convex should by default in all regards treat the impersonator as the impersonated user. But my Convex functions still seem to be functioning as though the value of the sub claim is the impersonator. Any clue why this might be happening? Anything I'm misunderstanding about how any of this works?
20 replies
CCConvex Community
Created by RJ on 11/9/2023 in #support-community
StorageId branded type and validator
It would be cool if StorageId were a branded type (like Id) rather than just a type alias, and it would also be cool if there were a validator for storage IDs (e.g. v.storageId()).
4 replies
CCConvex Community
Created by RJ on 10/30/2023 in #support-community
Math.random unsupported while evaluating schema
I'm working on my Effect wrapper library for Convex, and discovered through this work that importing a module which uses Math.random produces the following error when running convex dev:
400 Bad Request: Error: Hit an error while evaluating your schema:
Uncaught Error: Math.random unsupported when evaluating schema
400 Bad Request: Error: Hit an error while evaluating your schema:
Uncaught Error: Math.random unsupported when evaluating schema
1. Is there any way for me to work around this right now? 2. Would it be possible to treat Math.random in this context in the same way that it is treated in Convex functions?
73 replies