[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-convex-convex-create-component":3,"mdc-3x4168-key":35,"related-repo-convex-convex-create-component":4790,"related-org-convex-convex-create-component":4873},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":24,"repoUrl":25,"updatedAt":26,"license":27,"forks":28,"topics":29,"repo":30,"sourceUrl":33,"mdContent":34},"convex-create-component","build reusable Convex components","Builds reusable Convex components with isolated tables and app-facing APIs. Use for new components, reusable backend modules, integrations, or component boundary work.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"convex","Convex","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fconvex.png","get-convex",[13,17,18,21],{"name":14,"slug":15,"type":16},"Backend","backend","tag",{"name":9,"slug":8,"type":16},{"name":19,"slug":20,"type":16},"Architecture","architecture",{"name":22,"slug":23,"type":16},"API Development","api-development",34,"https:\u002F\u002Fgithub.com\u002Fget-convex\u002Fagent-skills","2026-07-12T08:00:39.428577",null,7,[],{"repoUrl":25,"stars":24,"forks":28,"topics":31,"description":32},[],"Convex Skills for Agents","https:\u002F\u002Fgithub.com\u002Fget-convex\u002Fagent-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fconvex-create-component","---\nname: convex-create-component\ndescription:\n  Builds reusable Convex components with isolated tables and app-facing APIs.\n  Use for new components, reusable backend modules, integrations, or component\n  boundary work.\n---\n\n# Convex Create Component\n\nCreate reusable Convex components with clear boundaries and a small app-facing\nAPI.\n\n## When to Use\n\n- Creating a new Convex component in an existing app\n- Extracting reusable backend logic into a component\n- Building a third-party integration that should own its own tables and\n  workflows\n- Packaging Convex functionality for reuse across multiple apps\n\n## When Not to Use\n\n- One-off business logic that belongs in the main app\n- Thin utilities that do not need Convex tables or functions\n- App-level orchestration that should stay in `convex\u002F`\n- Cases where a normal TypeScript library is enough\n\n## Workflow\n\n1. Ask the user what they are building and what the end goal is. If the repo\n   already makes the answer obvious, say so and confirm before proceeding.\n2. Choose the shape using the decision tree below and read the matching\n   reference file.\n3. Decide whether a component is justified. Prefer normal app code or a regular\n   library if the feature does not need isolated tables, backend functions, or\n   reusable persistent state.\n4. Make a short plan for:\n   - what tables the component owns\n   - what public functions it exposes\n   - what data must be passed in from the app (auth, env vars, parent IDs)\n   - what stays in the app as wrappers or HTTP mounts\n5. Create the component structure with `convex.config.ts`, `schema.ts`, and\n   function files.\n6. Implement functions using the component's own `.\u002F_generated\u002Fserver` imports,\n   not the app's generated files.\n7. Wire the component into the app with `app.use(...)`. If the app does not\n   already have `convex\u002Fconvex.config.ts`, create it.\n8. Call the component from the app through `components.\u003Cname>` using\n   `ctx.runQuery`, `ctx.runMutation`, or `ctx.runAction`.\n9. If React clients, HTTP callers, or public APIs need access, create wrapper\n   functions in the app instead of exposing component functions directly.\n10. Run `npx convex dev` and fix codegen, type, or boundary issues before\n    finishing.\n\n## Choose the Shape\n\nAsk the user, then pick one path:\n\n| Goal                                              | Shape            | Reference                           |\n| ------------------------------------------------- | ---------------- | ----------------------------------- |\n| Component for this app only                       | Local            | `references\u002Flocal-components.md`    |\n| Publish or share across apps                      | Packaged         | `references\u002Fpackaged-components.md` |\n| User explicitly needs local + shared library code | Hybrid           | `references\u002Fhybrid-components.md`   |\n| Not sure                                          | Default to local | `references\u002Flocal-components.md`    |\n\nRead exactly one reference file before proceeding.\n\n## Default Approach\n\nUnless the user explicitly wants an npm package, default to a local component:\n\n- Put it under `convex\u002Fcomponents\u002F\u003CcomponentName>\u002F`\n- Define it with `defineComponent(...)` in its own `convex.config.ts`\n- Install it from the app's `convex\u002Fconvex.config.ts` with `app.use(...)`\n- Let `npx convex dev` generate the component's own `_generated\u002F` files\n\n## Component Skeleton\n\nA minimal local component with a table and two functions, plus the app wiring.\n\n```ts\n\u002F\u002F convex\u002Fcomponents\u002Fnotifications\u002Fconvex.config.ts\nimport { defineComponent } from \"convex\u002Fserver\";\n\nexport default defineComponent(\"notifications\");\n```\n\n```ts\n\u002F\u002F convex\u002Fcomponents\u002Fnotifications\u002Fschema.ts\nimport { defineSchema, defineTable } from \"convex\u002Fserver\";\nimport { v } from \"convex\u002Fvalues\";\n\nexport default defineSchema({\n  notifications: defineTable({\n    userId: v.string(),\n    message: v.string(),\n    read: v.boolean(),\n  }).index(\"by_user_read\", [\"userId\", \"read\"]),\n});\n```\n\n```ts\n\u002F\u002F convex\u002Fcomponents\u002Fnotifications\u002Flib.ts\nimport { v } from \"convex\u002Fvalues\";\nimport { mutation, query } from \".\u002F_generated\u002Fserver.js\";\n\nexport const send = mutation({\n  args: { userId: v.string(), message: v.string() },\n  returns: v.id(\"notifications\"),\n  handler: async (ctx, args) => {\n    return await ctx.db.insert(\"notifications\", {\n      userId: args.userId,\n      message: args.message,\n      read: false,\n    });\n  },\n});\n\nexport const listUnread = query({\n  args: { userId: v.string() },\n  returns: v.array(\n    v.object({\n      _id: v.id(\"notifications\"),\n      _creationTime: v.number(),\n      userId: v.string(),\n      message: v.string(),\n      read: v.boolean(),\n    }),\n  ),\n  handler: async (ctx, args) => {\n    return await ctx.db\n      .query(\"notifications\")\n      .withIndex(\"by_user_read\", (q) =>\n        q.eq(\"userId\", args.userId).eq(\"read\", false),\n      )\n      .collect();\n  },\n});\n```\n\n```ts\n\u002F\u002F convex\u002Fconvex.config.ts\nimport { defineApp } from \"convex\u002Fserver\";\nimport notifications from \".\u002Fcomponents\u002Fnotifications\u002Fconvex.config.js\";\n\nconst app = defineApp();\napp.use(notifications);\n\nexport default app;\n```\n\n```ts\n\u002F\u002F convex\u002Fnotifications.ts  (app-side wrapper)\nimport { v } from \"convex\u002Fvalues\";\nimport { mutation, query } from \".\u002F_generated\u002Fserver\";\nimport { components } from \".\u002F_generated\u002Fapi\";\nimport { getAuthUserId } from \"@convex-dev\u002Fauth\u002Fserver\";\n\nexport const sendNotification = mutation({\n  args: { message: v.string() },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    const userId = await getAuthUserId(ctx);\n    if (!userId) throw new Error(\"Not authenticated\");\n\n    await ctx.runMutation(components.notifications.lib.send, {\n      userId,\n      message: args.message,\n    });\n    return null;\n  },\n});\n\nexport const myUnread = query({\n  args: {},\n  handler: async (ctx) => {\n    const userId = await getAuthUserId(ctx);\n    if (!userId) throw new Error(\"Not authenticated\");\n\n    return await ctx.runQuery(components.notifications.lib.listUnread, {\n      userId,\n    });\n  },\n});\n```\n\nNote the reference path shape: a function in\n`convex\u002Fcomponents\u002Fnotifications\u002Flib.ts` is called as\n`components.notifications.lib.send` from the app.\n\n## Critical Rules\n\n- Keep authentication in the app, because `ctx.auth` is not available inside\n  components.\n- Keep environment access in the app, because component functions cannot read\n  `process.env`.\n- Pass parent app IDs across the boundary as strings, because `Id` types become\n  plain strings in the app-facing `ComponentApi`.\n- Do not use `v.id(\"parentTable\")` for app-owned tables inside component args or\n  schema, because the component has no access to the app's table namespace.\n- Import `query`, `mutation`, and `action` from the component's own\n  `.\u002F_generated\u002Fserver`, not the app's generated files.\n- Do not expose component functions directly to clients. Create app wrappers\n  when client access is needed, because components are internal and need\n  auth\u002Fenv wiring the app provides.\n- If the component defines HTTP handlers, mount the routes in the app's\n  `convex\u002Fhttp.ts`, because components cannot register their own HTTP routes.\n- If the component needs pagination, use `paginator` from `convex-helpers`\n  instead of built-in `.paginate()`, because `.paginate()` does not work across\n  the component boundary.\n- Define indexes for queried fields instead of using Convex `.filter()` after a\n  database query.\n- Add `args` and `returns` validators to all public component functions, because\n  the component boundary requires explicit type contracts.\n\n## Patterns\n\n### Authentication and environment access\n\n```ts\n\u002F\u002F Bad: component code cannot rely on app auth or env\nconst identity = await ctx.auth.getUserIdentity();\nconst apiKey = process.env.OPENAI_API_KEY;\n```\n\n```ts\n\u002F\u002F Good: the app resolves auth and env, then passes explicit values\nconst userId = await getAuthUserId(ctx);\nif (!userId) throw new Error(\"Not authenticated\");\n\nawait ctx.runAction(components.translator.translate, {\n  userId,\n  apiKey: process.env.OPENAI_API_KEY,\n  text: args.text,\n});\n```\n\n### Client-facing API\n\n```ts\n\u002F\u002F Bad: assuming a component function is directly callable by clients\nexport const send = components.notifications.send;\n```\n\n```ts\n\u002F\u002F Good: re-export through an app mutation or query\nexport const sendNotification = mutation({\n  args: { message: v.string() },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    const userId = await getAuthUserId(ctx);\n    if (!userId) throw new Error(\"Not authenticated\");\n\n    await ctx.runMutation(components.notifications.lib.send, {\n      userId,\n      message: args.message,\n    });\n    return null;\n  },\n});\n```\n\n### IDs across the boundary\n\n```ts\n\u002F\u002F Bad: parent app table IDs are not valid component validators\nargs: {\n  userId: v.id(\"users\"),\n}\n```\n\n```ts\n\u002F\u002F Good: treat parent-owned IDs as strings at the boundary\nargs: {\n  userId: v.string(),\n}\n```\n\n### Advanced Patterns\n\nFor additional patterns including function handles for callbacks, deriving\nvalidators from schema, static configuration with a globals table, and\nclass-based client wrappers, see `references\u002Fadvanced-patterns.md`.\n\n## Validation\n\nTry validation in this order:\n\n1. `npx convex codegen --component-dir convex\u002Fcomponents\u002F\u003Cname>`\n2. `npx convex codegen`\n3. `npx convex dev`\n\nImportant:\n\n- Fresh repos may fail these commands until `CONVEX_DEPLOYMENT` is configured.\n- Until codegen runs, component-local `.\u002F_generated\u002F*` imports and app-side\n  `components.\u003Cname>...` references will not typecheck.\n- If validation blocks on Convex login or deployment setup, stop and ask the\n  user for that exact step instead of guessing.\n\n## Reference Files\n\nRead exactly one of these after the user confirms the goal:\n\n- `references\u002Flocal-components.md`\n- `references\u002Fpackaged-components.md`\n- `references\u002Fhybrid-components.md`\n\nOfficial docs:\n[Authoring Components](https:\u002F\u002Fdocs.convex.dev\u002Fcomponents\u002Fauthoring)\n\n## Checklist\n\n- [ ] Asked the user what they want to build and confirmed the shape\n- [ ] Read the matching reference file\n- [ ] Confirmed a component is the right abstraction\n- [ ] Planned tables, public API, boundaries, and app wrappers\n- [ ] Component lives under `convex\u002Fcomponents\u002F\u003Cname>\u002F` (or package layout if\n      publishing)\n- [ ] Component imports from its own `.\u002F_generated\u002Fserver`\n- [ ] Auth, env access, and HTTP routes stay in the app\n- [ ] Parent app IDs cross the boundary as `v.string()`\n- [ ] Public functions have `args` and `returns` validators\n- [ ] Ran `npx convex dev` and fixed codegen or type issues\n",{"data":36,"body":37},{"name":4,"description":6},{"type":38,"children":39},"root",[40,48,54,61,86,92,122,128,284,290,295,415,420,426,431,500,506,511,643,1014,2169,2347,3260,3281,3287,3470,3476,3483,3591,3846,3852,3910,4323,4329,4416,4484,4490,4502,4508,4513,4542,4547,4589,4595,4600,4627,4641,4647,4784],{"type":41,"tag":42,"props":43,"children":44},"element","h1",{"id":4},[45],{"type":46,"value":47},"text","Convex Create Component",{"type":41,"tag":49,"props":50,"children":51},"p",{},[52],{"type":46,"value":53},"Create reusable Convex components with clear boundaries and a small app-facing\nAPI.",{"type":41,"tag":55,"props":56,"children":58},"h2",{"id":57},"when-to-use",[59],{"type":46,"value":60},"When to Use",{"type":41,"tag":62,"props":63,"children":64},"ul",{},[65,71,76,81],{"type":41,"tag":66,"props":67,"children":68},"li",{},[69],{"type":46,"value":70},"Creating a new Convex component in an existing app",{"type":41,"tag":66,"props":72,"children":73},{},[74],{"type":46,"value":75},"Extracting reusable backend logic into a component",{"type":41,"tag":66,"props":77,"children":78},{},[79],{"type":46,"value":80},"Building a third-party integration that should own its own tables and\nworkflows",{"type":41,"tag":66,"props":82,"children":83},{},[84],{"type":46,"value":85},"Packaging Convex functionality for reuse across multiple apps",{"type":41,"tag":55,"props":87,"children":89},{"id":88},"when-not-to-use",[90],{"type":46,"value":91},"When Not to Use",{"type":41,"tag":62,"props":93,"children":94},{},[95,100,105,117],{"type":41,"tag":66,"props":96,"children":97},{},[98],{"type":46,"value":99},"One-off business logic that belongs in the main app",{"type":41,"tag":66,"props":101,"children":102},{},[103],{"type":46,"value":104},"Thin utilities that do not need Convex tables or functions",{"type":41,"tag":66,"props":106,"children":107},{},[108,110],{"type":46,"value":109},"App-level orchestration that should stay in ",{"type":41,"tag":111,"props":112,"children":114},"code",{"className":113},[],[115],{"type":46,"value":116},"convex\u002F",{"type":41,"tag":66,"props":118,"children":119},{},[120],{"type":46,"value":121},"Cases where a normal TypeScript library is enough",{"type":41,"tag":55,"props":123,"children":125},{"id":124},"workflow",[126],{"type":46,"value":127},"Workflow",{"type":41,"tag":129,"props":130,"children":131},"ol",{},[132,137,142,147,175,196,209,230,266,271],{"type":41,"tag":66,"props":133,"children":134},{},[135],{"type":46,"value":136},"Ask the user what they are building and what the end goal is. If the repo\nalready makes the answer obvious, say so and confirm before proceeding.",{"type":41,"tag":66,"props":138,"children":139},{},[140],{"type":46,"value":141},"Choose the shape using the decision tree below and read the matching\nreference file.",{"type":41,"tag":66,"props":143,"children":144},{},[145],{"type":46,"value":146},"Decide whether a component is justified. Prefer normal app code or a regular\nlibrary if the feature does not need isolated tables, backend functions, or\nreusable persistent state.",{"type":41,"tag":66,"props":148,"children":149},{},[150,152],{"type":46,"value":151},"Make a short plan for:\n",{"type":41,"tag":62,"props":153,"children":154},{},[155,160,165,170],{"type":41,"tag":66,"props":156,"children":157},{},[158],{"type":46,"value":159},"what tables the component owns",{"type":41,"tag":66,"props":161,"children":162},{},[163],{"type":46,"value":164},"what public functions it exposes",{"type":41,"tag":66,"props":166,"children":167},{},[168],{"type":46,"value":169},"what data must be passed in from the app (auth, env vars, parent IDs)",{"type":41,"tag":66,"props":171,"children":172},{},[173],{"type":46,"value":174},"what stays in the app as wrappers or HTTP mounts",{"type":41,"tag":66,"props":176,"children":177},{},[178,180,186,188,194],{"type":46,"value":179},"Create the component structure with ",{"type":41,"tag":111,"props":181,"children":183},{"className":182},[],[184],{"type":46,"value":185},"convex.config.ts",{"type":46,"value":187},", ",{"type":41,"tag":111,"props":189,"children":191},{"className":190},[],[192],{"type":46,"value":193},"schema.ts",{"type":46,"value":195},", and\nfunction files.",{"type":41,"tag":66,"props":197,"children":198},{},[199,201,207],{"type":46,"value":200},"Implement functions using the component's own ",{"type":41,"tag":111,"props":202,"children":204},{"className":203},[],[205],{"type":46,"value":206},".\u002F_generated\u002Fserver",{"type":46,"value":208}," imports,\nnot the app's generated files.",{"type":41,"tag":66,"props":210,"children":211},{},[212,214,220,222,228],{"type":46,"value":213},"Wire the component into the app with ",{"type":41,"tag":111,"props":215,"children":217},{"className":216},[],[218],{"type":46,"value":219},"app.use(...)",{"type":46,"value":221},". If the app does not\nalready have ",{"type":41,"tag":111,"props":223,"children":225},{"className":224},[],[226],{"type":46,"value":227},"convex\u002Fconvex.config.ts",{"type":46,"value":229},", create it.",{"type":41,"tag":66,"props":231,"children":232},{},[233,235,241,243,249,250,256,258,264],{"type":46,"value":234},"Call the component from the app through ",{"type":41,"tag":111,"props":236,"children":238},{"className":237},[],[239],{"type":46,"value":240},"components.\u003Cname>",{"type":46,"value":242}," using\n",{"type":41,"tag":111,"props":244,"children":246},{"className":245},[],[247],{"type":46,"value":248},"ctx.runQuery",{"type":46,"value":187},{"type":41,"tag":111,"props":251,"children":253},{"className":252},[],[254],{"type":46,"value":255},"ctx.runMutation",{"type":46,"value":257},", or ",{"type":41,"tag":111,"props":259,"children":261},{"className":260},[],[262],{"type":46,"value":263},"ctx.runAction",{"type":46,"value":265},".",{"type":41,"tag":66,"props":267,"children":268},{},[269],{"type":46,"value":270},"If React clients, HTTP callers, or public APIs need access, create wrapper\nfunctions in the app instead of exposing component functions directly.",{"type":41,"tag":66,"props":272,"children":273},{},[274,276,282],{"type":46,"value":275},"Run ",{"type":41,"tag":111,"props":277,"children":279},{"className":278},[],[280],{"type":46,"value":281},"npx convex dev",{"type":46,"value":283}," and fix codegen, type, or boundary issues before\nfinishing.",{"type":41,"tag":55,"props":285,"children":287},{"id":286},"choose-the-shape",[288],{"type":46,"value":289},"Choose the Shape",{"type":41,"tag":49,"props":291,"children":292},{},[293],{"type":46,"value":294},"Ask the user, then pick one path:",{"type":41,"tag":296,"props":297,"children":298},"table",{},[299,323],{"type":41,"tag":300,"props":301,"children":302},"thead",{},[303],{"type":41,"tag":304,"props":305,"children":306},"tr",{},[307,313,318],{"type":41,"tag":308,"props":309,"children":310},"th",{},[311],{"type":46,"value":312},"Goal",{"type":41,"tag":308,"props":314,"children":315},{},[316],{"type":46,"value":317},"Shape",{"type":41,"tag":308,"props":319,"children":320},{},[321],{"type":46,"value":322},"Reference",{"type":41,"tag":324,"props":325,"children":326},"tbody",{},[327,350,372,394],{"type":41,"tag":304,"props":328,"children":329},{},[330,336,341],{"type":41,"tag":331,"props":332,"children":333},"td",{},[334],{"type":46,"value":335},"Component for this app only",{"type":41,"tag":331,"props":337,"children":338},{},[339],{"type":46,"value":340},"Local",{"type":41,"tag":331,"props":342,"children":343},{},[344],{"type":41,"tag":111,"props":345,"children":347},{"className":346},[],[348],{"type":46,"value":349},"references\u002Flocal-components.md",{"type":41,"tag":304,"props":351,"children":352},{},[353,358,363],{"type":41,"tag":331,"props":354,"children":355},{},[356],{"type":46,"value":357},"Publish or share across apps",{"type":41,"tag":331,"props":359,"children":360},{},[361],{"type":46,"value":362},"Packaged",{"type":41,"tag":331,"props":364,"children":365},{},[366],{"type":41,"tag":111,"props":367,"children":369},{"className":368},[],[370],{"type":46,"value":371},"references\u002Fpackaged-components.md",{"type":41,"tag":304,"props":373,"children":374},{},[375,380,385],{"type":41,"tag":331,"props":376,"children":377},{},[378],{"type":46,"value":379},"User explicitly needs local + shared library code",{"type":41,"tag":331,"props":381,"children":382},{},[383],{"type":46,"value":384},"Hybrid",{"type":41,"tag":331,"props":386,"children":387},{},[388],{"type":41,"tag":111,"props":389,"children":391},{"className":390},[],[392],{"type":46,"value":393},"references\u002Fhybrid-components.md",{"type":41,"tag":304,"props":395,"children":396},{},[397,402,407],{"type":41,"tag":331,"props":398,"children":399},{},[400],{"type":46,"value":401},"Not sure",{"type":41,"tag":331,"props":403,"children":404},{},[405],{"type":46,"value":406},"Default to local",{"type":41,"tag":331,"props":408,"children":409},{},[410],{"type":41,"tag":111,"props":411,"children":413},{"className":412},[],[414],{"type":46,"value":349},{"type":41,"tag":49,"props":416,"children":417},{},[418],{"type":46,"value":419},"Read exactly one reference file before proceeding.",{"type":41,"tag":55,"props":421,"children":423},{"id":422},"default-approach",[424],{"type":46,"value":425},"Default Approach",{"type":41,"tag":49,"props":427,"children":428},{},[429],{"type":46,"value":430},"Unless the user explicitly wants an npm package, default to a local component:",{"type":41,"tag":62,"props":432,"children":433},{},[434,445,463,480],{"type":41,"tag":66,"props":435,"children":436},{},[437,439],{"type":46,"value":438},"Put it under ",{"type":41,"tag":111,"props":440,"children":442},{"className":441},[],[443],{"type":46,"value":444},"convex\u002Fcomponents\u002F\u003CcomponentName>\u002F",{"type":41,"tag":66,"props":446,"children":447},{},[448,450,456,458],{"type":46,"value":449},"Define it with ",{"type":41,"tag":111,"props":451,"children":453},{"className":452},[],[454],{"type":46,"value":455},"defineComponent(...)",{"type":46,"value":457}," in its own ",{"type":41,"tag":111,"props":459,"children":461},{"className":460},[],[462],{"type":46,"value":185},{"type":41,"tag":66,"props":464,"children":465},{},[466,468,473,475],{"type":46,"value":467},"Install it from the app's ",{"type":41,"tag":111,"props":469,"children":471},{"className":470},[],[472],{"type":46,"value":227},{"type":46,"value":474}," with ",{"type":41,"tag":111,"props":476,"children":478},{"className":477},[],[479],{"type":46,"value":219},{"type":41,"tag":66,"props":481,"children":482},{},[483,485,490,492,498],{"type":46,"value":484},"Let ",{"type":41,"tag":111,"props":486,"children":488},{"className":487},[],[489],{"type":46,"value":281},{"type":46,"value":491}," generate the component's own ",{"type":41,"tag":111,"props":493,"children":495},{"className":494},[],[496],{"type":46,"value":497},"_generated\u002F",{"type":46,"value":499}," files",{"type":41,"tag":55,"props":501,"children":503},{"id":502},"component-skeleton",[504],{"type":46,"value":505},"Component Skeleton",{"type":41,"tag":49,"props":507,"children":508},{},[509],{"type":46,"value":510},"A minimal local component with a table and two functions, plus the app wiring.",{"type":41,"tag":512,"props":513,"children":518},"pre",{"className":514,"code":515,"language":516,"meta":517,"style":517},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F convex\u002Fcomponents\u002Fnotifications\u002Fconvex.config.ts\nimport { defineComponent } from \"convex\u002Fserver\";\n\nexport default defineComponent(\"notifications\");\n","ts","",[519],{"type":41,"tag":111,"props":520,"children":521},{"__ignoreMap":517},[522,534,587,597],{"type":41,"tag":523,"props":524,"children":527},"span",{"class":525,"line":526},"line",1,[528],{"type":41,"tag":523,"props":529,"children":531},{"style":530},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[532],{"type":46,"value":533},"\u002F\u002F convex\u002Fcomponents\u002Fnotifications\u002Fconvex.config.ts\n",{"type":41,"tag":523,"props":535,"children":537},{"class":525,"line":536},2,[538,544,550,556,561,566,571,577,582],{"type":41,"tag":523,"props":539,"children":541},{"style":540},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[542],{"type":46,"value":543},"import",{"type":41,"tag":523,"props":545,"children":547},{"style":546},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[548],{"type":46,"value":549}," {",{"type":41,"tag":523,"props":551,"children":553},{"style":552},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[554],{"type":46,"value":555}," defineComponent",{"type":41,"tag":523,"props":557,"children":558},{"style":546},[559],{"type":46,"value":560}," }",{"type":41,"tag":523,"props":562,"children":563},{"style":540},[564],{"type":46,"value":565}," from",{"type":41,"tag":523,"props":567,"children":568},{"style":546},[569],{"type":46,"value":570}," \"",{"type":41,"tag":523,"props":572,"children":574},{"style":573},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[575],{"type":46,"value":576},"convex\u002Fserver",{"type":41,"tag":523,"props":578,"children":579},{"style":546},[580],{"type":46,"value":581},"\"",{"type":41,"tag":523,"props":583,"children":584},{"style":546},[585],{"type":46,"value":586},";\n",{"type":41,"tag":523,"props":588,"children":590},{"class":525,"line":589},3,[591],{"type":41,"tag":523,"props":592,"children":594},{"emptyLinePlaceholder":593},true,[595],{"type":46,"value":596},"\n",{"type":41,"tag":523,"props":598,"children":600},{"class":525,"line":599},4,[601,606,611,616,621,625,630,634,639],{"type":41,"tag":523,"props":602,"children":603},{"style":540},[604],{"type":46,"value":605},"export",{"type":41,"tag":523,"props":607,"children":608},{"style":540},[609],{"type":46,"value":610}," default",{"type":41,"tag":523,"props":612,"children":614},{"style":613},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[615],{"type":46,"value":555},{"type":41,"tag":523,"props":617,"children":618},{"style":552},[619],{"type":46,"value":620},"(",{"type":41,"tag":523,"props":622,"children":623},{"style":546},[624],{"type":46,"value":581},{"type":41,"tag":523,"props":626,"children":627},{"style":573},[628],{"type":46,"value":629},"notifications",{"type":41,"tag":523,"props":631,"children":632},{"style":546},[633],{"type":46,"value":581},{"type":41,"tag":523,"props":635,"children":636},{"style":552},[637],{"type":46,"value":638},")",{"type":41,"tag":523,"props":640,"children":641},{"style":546},[642],{"type":46,"value":586},{"type":41,"tag":512,"props":644,"children":646},{"className":514,"code":645,"language":516,"meta":517,"style":517},"\u002F\u002F convex\u002Fcomponents\u002Fnotifications\u002Fschema.ts\nimport { defineSchema, defineTable } from \"convex\u002Fserver\";\nimport { v } from \"convex\u002Fvalues\";\n\nexport default defineSchema({\n  notifications: defineTable({\n    userId: v.string(),\n    message: v.string(),\n    read: v.boolean(),\n  }).index(\"by_user_read\", [\"userId\", \"read\"]),\n});\n",[647],{"type":41,"tag":111,"props":648,"children":649},{"__ignoreMap":517},[650,658,708,749,756,781,808,843,876,910,997],{"type":41,"tag":523,"props":651,"children":652},{"class":525,"line":526},[653],{"type":41,"tag":523,"props":654,"children":655},{"style":530},[656],{"type":46,"value":657},"\u002F\u002F convex\u002Fcomponents\u002Fnotifications\u002Fschema.ts\n",{"type":41,"tag":523,"props":659,"children":660},{"class":525,"line":536},[661,665,669,674,679,684,688,692,696,700,704],{"type":41,"tag":523,"props":662,"children":663},{"style":540},[664],{"type":46,"value":543},{"type":41,"tag":523,"props":666,"children":667},{"style":546},[668],{"type":46,"value":549},{"type":41,"tag":523,"props":670,"children":671},{"style":552},[672],{"type":46,"value":673}," defineSchema",{"type":41,"tag":523,"props":675,"children":676},{"style":546},[677],{"type":46,"value":678},",",{"type":41,"tag":523,"props":680,"children":681},{"style":552},[682],{"type":46,"value":683}," defineTable",{"type":41,"tag":523,"props":685,"children":686},{"style":546},[687],{"type":46,"value":560},{"type":41,"tag":523,"props":689,"children":690},{"style":540},[691],{"type":46,"value":565},{"type":41,"tag":523,"props":693,"children":694},{"style":546},[695],{"type":46,"value":570},{"type":41,"tag":523,"props":697,"children":698},{"style":573},[699],{"type":46,"value":576},{"type":41,"tag":523,"props":701,"children":702},{"style":546},[703],{"type":46,"value":581},{"type":41,"tag":523,"props":705,"children":706},{"style":546},[707],{"type":46,"value":586},{"type":41,"tag":523,"props":709,"children":710},{"class":525,"line":589},[711,715,719,724,728,732,736,741,745],{"type":41,"tag":523,"props":712,"children":713},{"style":540},[714],{"type":46,"value":543},{"type":41,"tag":523,"props":716,"children":717},{"style":546},[718],{"type":46,"value":549},{"type":41,"tag":523,"props":720,"children":721},{"style":552},[722],{"type":46,"value":723}," v",{"type":41,"tag":523,"props":725,"children":726},{"style":546},[727],{"type":46,"value":560},{"type":41,"tag":523,"props":729,"children":730},{"style":540},[731],{"type":46,"value":565},{"type":41,"tag":523,"props":733,"children":734},{"style":546},[735],{"type":46,"value":570},{"type":41,"tag":523,"props":737,"children":738},{"style":573},[739],{"type":46,"value":740},"convex\u002Fvalues",{"type":41,"tag":523,"props":742,"children":743},{"style":546},[744],{"type":46,"value":581},{"type":41,"tag":523,"props":746,"children":747},{"style":546},[748],{"type":46,"value":586},{"type":41,"tag":523,"props":750,"children":751},{"class":525,"line":599},[752],{"type":41,"tag":523,"props":753,"children":754},{"emptyLinePlaceholder":593},[755],{"type":46,"value":596},{"type":41,"tag":523,"props":757,"children":759},{"class":525,"line":758},5,[760,764,768,772,776],{"type":41,"tag":523,"props":761,"children":762},{"style":540},[763],{"type":46,"value":605},{"type":41,"tag":523,"props":765,"children":766},{"style":540},[767],{"type":46,"value":610},{"type":41,"tag":523,"props":769,"children":770},{"style":613},[771],{"type":46,"value":673},{"type":41,"tag":523,"props":773,"children":774},{"style":552},[775],{"type":46,"value":620},{"type":41,"tag":523,"props":777,"children":778},{"style":546},[779],{"type":46,"value":780},"{\n",{"type":41,"tag":523,"props":782,"children":784},{"class":525,"line":783},6,[785,791,796,800,804],{"type":41,"tag":523,"props":786,"children":788},{"style":787},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[789],{"type":46,"value":790},"  notifications",{"type":41,"tag":523,"props":792,"children":793},{"style":546},[794],{"type":46,"value":795},":",{"type":41,"tag":523,"props":797,"children":798},{"style":613},[799],{"type":46,"value":683},{"type":41,"tag":523,"props":801,"children":802},{"style":552},[803],{"type":46,"value":620},{"type":41,"tag":523,"props":805,"children":806},{"style":546},[807],{"type":46,"value":780},{"type":41,"tag":523,"props":809,"children":810},{"class":525,"line":28},[811,816,820,824,828,833,838],{"type":41,"tag":523,"props":812,"children":813},{"style":787},[814],{"type":46,"value":815},"    userId",{"type":41,"tag":523,"props":817,"children":818},{"style":546},[819],{"type":46,"value":795},{"type":41,"tag":523,"props":821,"children":822},{"style":552},[823],{"type":46,"value":723},{"type":41,"tag":523,"props":825,"children":826},{"style":546},[827],{"type":46,"value":265},{"type":41,"tag":523,"props":829,"children":830},{"style":613},[831],{"type":46,"value":832},"string",{"type":41,"tag":523,"props":834,"children":835},{"style":552},[836],{"type":46,"value":837},"()",{"type":41,"tag":523,"props":839,"children":840},{"style":546},[841],{"type":46,"value":842},",\n",{"type":41,"tag":523,"props":844,"children":846},{"class":525,"line":845},8,[847,852,856,860,864,868,872],{"type":41,"tag":523,"props":848,"children":849},{"style":787},[850],{"type":46,"value":851},"    message",{"type":41,"tag":523,"props":853,"children":854},{"style":546},[855],{"type":46,"value":795},{"type":41,"tag":523,"props":857,"children":858},{"style":552},[859],{"type":46,"value":723},{"type":41,"tag":523,"props":861,"children":862},{"style":546},[863],{"type":46,"value":265},{"type":41,"tag":523,"props":865,"children":866},{"style":613},[867],{"type":46,"value":832},{"type":41,"tag":523,"props":869,"children":870},{"style":552},[871],{"type":46,"value":837},{"type":41,"tag":523,"props":873,"children":874},{"style":546},[875],{"type":46,"value":842},{"type":41,"tag":523,"props":877,"children":879},{"class":525,"line":878},9,[880,885,889,893,897,902,906],{"type":41,"tag":523,"props":881,"children":882},{"style":787},[883],{"type":46,"value":884},"    read",{"type":41,"tag":523,"props":886,"children":887},{"style":546},[888],{"type":46,"value":795},{"type":41,"tag":523,"props":890,"children":891},{"style":552},[892],{"type":46,"value":723},{"type":41,"tag":523,"props":894,"children":895},{"style":546},[896],{"type":46,"value":265},{"type":41,"tag":523,"props":898,"children":899},{"style":613},[900],{"type":46,"value":901},"boolean",{"type":41,"tag":523,"props":903,"children":904},{"style":552},[905],{"type":46,"value":837},{"type":41,"tag":523,"props":907,"children":908},{"style":546},[909],{"type":46,"value":842},{"type":41,"tag":523,"props":911,"children":913},{"class":525,"line":912},10,[914,919,923,927,932,936,940,945,949,953,958,962,967,971,975,979,984,988,993],{"type":41,"tag":523,"props":915,"children":916},{"style":546},[917],{"type":46,"value":918},"  }",{"type":41,"tag":523,"props":920,"children":921},{"style":552},[922],{"type":46,"value":638},{"type":41,"tag":523,"props":924,"children":925},{"style":546},[926],{"type":46,"value":265},{"type":41,"tag":523,"props":928,"children":929},{"style":613},[930],{"type":46,"value":931},"index",{"type":41,"tag":523,"props":933,"children":934},{"style":552},[935],{"type":46,"value":620},{"type":41,"tag":523,"props":937,"children":938},{"style":546},[939],{"type":46,"value":581},{"type":41,"tag":523,"props":941,"children":942},{"style":573},[943],{"type":46,"value":944},"by_user_read",{"type":41,"tag":523,"props":946,"children":947},{"style":546},[948],{"type":46,"value":581},{"type":41,"tag":523,"props":950,"children":951},{"style":546},[952],{"type":46,"value":678},{"type":41,"tag":523,"props":954,"children":955},{"style":552},[956],{"type":46,"value":957}," [",{"type":41,"tag":523,"props":959,"children":960},{"style":546},[961],{"type":46,"value":581},{"type":41,"tag":523,"props":963,"children":964},{"style":573},[965],{"type":46,"value":966},"userId",{"type":41,"tag":523,"props":968,"children":969},{"style":546},[970],{"type":46,"value":581},{"type":41,"tag":523,"props":972,"children":973},{"style":546},[974],{"type":46,"value":678},{"type":41,"tag":523,"props":976,"children":977},{"style":546},[978],{"type":46,"value":570},{"type":41,"tag":523,"props":980,"children":981},{"style":573},[982],{"type":46,"value":983},"read",{"type":41,"tag":523,"props":985,"children":986},{"style":546},[987],{"type":46,"value":581},{"type":41,"tag":523,"props":989,"children":990},{"style":552},[991],{"type":46,"value":992},"])",{"type":41,"tag":523,"props":994,"children":995},{"style":546},[996],{"type":46,"value":842},{"type":41,"tag":523,"props":998,"children":1000},{"class":525,"line":999},11,[1001,1006,1010],{"type":41,"tag":523,"props":1002,"children":1003},{"style":546},[1004],{"type":46,"value":1005},"}",{"type":41,"tag":523,"props":1007,"children":1008},{"style":552},[1009],{"type":46,"value":638},{"type":41,"tag":523,"props":1011,"children":1012},{"style":546},[1013],{"type":46,"value":586},{"type":41,"tag":512,"props":1015,"children":1017},{"className":514,"code":1016,"language":516,"meta":517,"style":517},"\u002F\u002F convex\u002Fcomponents\u002Fnotifications\u002Flib.ts\nimport { v } from \"convex\u002Fvalues\";\nimport { mutation, query } from \".\u002F_generated\u002Fserver.js\";\n\nexport const send = mutation({\n  args: { userId: v.string(), message: v.string() },\n  returns: v.id(\"notifications\"),\n  handler: async (ctx, args) => {\n    return await ctx.db.insert(\"notifications\", {\n      userId: args.userId,\n      message: args.message,\n      read: false,\n    });\n  },\n});\n\nexport const listUnread = query({\n  args: { userId: v.string() },\n  returns: v.array(\n    v.object({\n      _id: v.id(\"notifications\"),\n      _creationTime: v.number(),\n      userId: v.string(),\n      message: v.string(),\n      read: v.boolean(),\n    }),\n  ),\n  handler: async (ctx, args) => {\n    return await ctx.db\n      .query(\"notifications\")\n      .withIndex(\"by_user_read\", (q) =>\n        q.eq(\"userId\", args.userId).eq(\"read\", false),\n      )\n      .collect();\n  },\n});\n",[1018],{"type":41,"tag":111,"props":1019,"children":1020},{"__ignoreMap":517},[1021,1029,1068,1118,1125,1160,1236,1285,1336,1396,1424,1453,1476,1493,1502,1518,1526,1559,1603,1633,1659,1708,1742,1774,1806,1838,1854,1867,1911,1936,1971,2022,2116,2125,2145,2153],{"type":41,"tag":523,"props":1022,"children":1023},{"class":525,"line":526},[1024],{"type":41,"tag":523,"props":1025,"children":1026},{"style":530},[1027],{"type":46,"value":1028},"\u002F\u002F convex\u002Fcomponents\u002Fnotifications\u002Flib.ts\n",{"type":41,"tag":523,"props":1030,"children":1031},{"class":525,"line":536},[1032,1036,1040,1044,1048,1052,1056,1060,1064],{"type":41,"tag":523,"props":1033,"children":1034},{"style":540},[1035],{"type":46,"value":543},{"type":41,"tag":523,"props":1037,"children":1038},{"style":546},[1039],{"type":46,"value":549},{"type":41,"tag":523,"props":1041,"children":1042},{"style":552},[1043],{"type":46,"value":723},{"type":41,"tag":523,"props":1045,"children":1046},{"style":546},[1047],{"type":46,"value":560},{"type":41,"tag":523,"props":1049,"children":1050},{"style":540},[1051],{"type":46,"value":565},{"type":41,"tag":523,"props":1053,"children":1054},{"style":546},[1055],{"type":46,"value":570},{"type":41,"tag":523,"props":1057,"children":1058},{"style":573},[1059],{"type":46,"value":740},{"type":41,"tag":523,"props":1061,"children":1062},{"style":546},[1063],{"type":46,"value":581},{"type":41,"tag":523,"props":1065,"children":1066},{"style":546},[1067],{"type":46,"value":586},{"type":41,"tag":523,"props":1069,"children":1070},{"class":525,"line":589},[1071,1075,1079,1084,1088,1093,1097,1101,1105,1110,1114],{"type":41,"tag":523,"props":1072,"children":1073},{"style":540},[1074],{"type":46,"value":543},{"type":41,"tag":523,"props":1076,"children":1077},{"style":546},[1078],{"type":46,"value":549},{"type":41,"tag":523,"props":1080,"children":1081},{"style":552},[1082],{"type":46,"value":1083}," mutation",{"type":41,"tag":523,"props":1085,"children":1086},{"style":546},[1087],{"type":46,"value":678},{"type":41,"tag":523,"props":1089,"children":1090},{"style":552},[1091],{"type":46,"value":1092}," query",{"type":41,"tag":523,"props":1094,"children":1095},{"style":546},[1096],{"type":46,"value":560},{"type":41,"tag":523,"props":1098,"children":1099},{"style":540},[1100],{"type":46,"value":565},{"type":41,"tag":523,"props":1102,"children":1103},{"style":546},[1104],{"type":46,"value":570},{"type":41,"tag":523,"props":1106,"children":1107},{"style":573},[1108],{"type":46,"value":1109},".\u002F_generated\u002Fserver.js",{"type":41,"tag":523,"props":1111,"children":1112},{"style":546},[1113],{"type":46,"value":581},{"type":41,"tag":523,"props":1115,"children":1116},{"style":546},[1117],{"type":46,"value":586},{"type":41,"tag":523,"props":1119,"children":1120},{"class":525,"line":599},[1121],{"type":41,"tag":523,"props":1122,"children":1123},{"emptyLinePlaceholder":593},[1124],{"type":46,"value":596},{"type":41,"tag":523,"props":1126,"children":1127},{"class":525,"line":758},[1128,1132,1138,1143,1148,1152,1156],{"type":41,"tag":523,"props":1129,"children":1130},{"style":540},[1131],{"type":46,"value":605},{"type":41,"tag":523,"props":1133,"children":1135},{"style":1134},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[1136],{"type":46,"value":1137}," const",{"type":41,"tag":523,"props":1139,"children":1140},{"style":552},[1141],{"type":46,"value":1142}," send ",{"type":41,"tag":523,"props":1144,"children":1145},{"style":546},[1146],{"type":46,"value":1147},"=",{"type":41,"tag":523,"props":1149,"children":1150},{"style":613},[1151],{"type":46,"value":1083},{"type":41,"tag":523,"props":1153,"children":1154},{"style":552},[1155],{"type":46,"value":620},{"type":41,"tag":523,"props":1157,"children":1158},{"style":546},[1159],{"type":46,"value":780},{"type":41,"tag":523,"props":1161,"children":1162},{"class":525,"line":783},[1163,1168,1172,1176,1181,1185,1189,1193,1197,1201,1205,1210,1214,1218,1222,1226,1231],{"type":41,"tag":523,"props":1164,"children":1165},{"style":787},[1166],{"type":46,"value":1167},"  args",{"type":41,"tag":523,"props":1169,"children":1170},{"style":546},[1171],{"type":46,"value":795},{"type":41,"tag":523,"props":1173,"children":1174},{"style":546},[1175],{"type":46,"value":549},{"type":41,"tag":523,"props":1177,"children":1178},{"style":787},[1179],{"type":46,"value":1180}," userId",{"type":41,"tag":523,"props":1182,"children":1183},{"style":546},[1184],{"type":46,"value":795},{"type":41,"tag":523,"props":1186,"children":1187},{"style":552},[1188],{"type":46,"value":723},{"type":41,"tag":523,"props":1190,"children":1191},{"style":546},[1192],{"type":46,"value":265},{"type":41,"tag":523,"props":1194,"children":1195},{"style":613},[1196],{"type":46,"value":832},{"type":41,"tag":523,"props":1198,"children":1199},{"style":552},[1200],{"type":46,"value":837},{"type":41,"tag":523,"props":1202,"children":1203},{"style":546},[1204],{"type":46,"value":678},{"type":41,"tag":523,"props":1206,"children":1207},{"style":787},[1208],{"type":46,"value":1209}," message",{"type":41,"tag":523,"props":1211,"children":1212},{"style":546},[1213],{"type":46,"value":795},{"type":41,"tag":523,"props":1215,"children":1216},{"style":552},[1217],{"type":46,"value":723},{"type":41,"tag":523,"props":1219,"children":1220},{"style":546},[1221],{"type":46,"value":265},{"type":41,"tag":523,"props":1223,"children":1224},{"style":613},[1225],{"type":46,"value":832},{"type":41,"tag":523,"props":1227,"children":1228},{"style":552},[1229],{"type":46,"value":1230},"() ",{"type":41,"tag":523,"props":1232,"children":1233},{"style":546},[1234],{"type":46,"value":1235},"},\n",{"type":41,"tag":523,"props":1237,"children":1238},{"class":525,"line":28},[1239,1244,1248,1252,1256,1261,1265,1269,1273,1277,1281],{"type":41,"tag":523,"props":1240,"children":1241},{"style":787},[1242],{"type":46,"value":1243},"  returns",{"type":41,"tag":523,"props":1245,"children":1246},{"style":546},[1247],{"type":46,"value":795},{"type":41,"tag":523,"props":1249,"children":1250},{"style":552},[1251],{"type":46,"value":723},{"type":41,"tag":523,"props":1253,"children":1254},{"style":546},[1255],{"type":46,"value":265},{"type":41,"tag":523,"props":1257,"children":1258},{"style":613},[1259],{"type":46,"value":1260},"id",{"type":41,"tag":523,"props":1262,"children":1263},{"style":552},[1264],{"type":46,"value":620},{"type":41,"tag":523,"props":1266,"children":1267},{"style":546},[1268],{"type":46,"value":581},{"type":41,"tag":523,"props":1270,"children":1271},{"style":573},[1272],{"type":46,"value":629},{"type":41,"tag":523,"props":1274,"children":1275},{"style":546},[1276],{"type":46,"value":581},{"type":41,"tag":523,"props":1278,"children":1279},{"style":552},[1280],{"type":46,"value":638},{"type":41,"tag":523,"props":1282,"children":1283},{"style":546},[1284],{"type":46,"value":842},{"type":41,"tag":523,"props":1286,"children":1287},{"class":525,"line":845},[1288,1293,1297,1302,1307,1313,1317,1322,1326,1331],{"type":41,"tag":523,"props":1289,"children":1290},{"style":613},[1291],{"type":46,"value":1292},"  handler",{"type":41,"tag":523,"props":1294,"children":1295},{"style":546},[1296],{"type":46,"value":795},{"type":41,"tag":523,"props":1298,"children":1299},{"style":1134},[1300],{"type":46,"value":1301}," async",{"type":41,"tag":523,"props":1303,"children":1304},{"style":546},[1305],{"type":46,"value":1306}," (",{"type":41,"tag":523,"props":1308,"children":1310},{"style":1309},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic",[1311],{"type":46,"value":1312},"ctx",{"type":41,"tag":523,"props":1314,"children":1315},{"style":546},[1316],{"type":46,"value":678},{"type":41,"tag":523,"props":1318,"children":1319},{"style":1309},[1320],{"type":46,"value":1321}," args",{"type":41,"tag":523,"props":1323,"children":1324},{"style":546},[1325],{"type":46,"value":638},{"type":41,"tag":523,"props":1327,"children":1328},{"style":1134},[1329],{"type":46,"value":1330}," =>",{"type":41,"tag":523,"props":1332,"children":1333},{"style":546},[1334],{"type":46,"value":1335}," {\n",{"type":41,"tag":523,"props":1337,"children":1338},{"class":525,"line":878},[1339,1344,1349,1354,1358,1363,1367,1372,1376,1380,1384,1388,1392],{"type":41,"tag":523,"props":1340,"children":1341},{"style":540},[1342],{"type":46,"value":1343},"    return",{"type":41,"tag":523,"props":1345,"children":1346},{"style":540},[1347],{"type":46,"value":1348}," await",{"type":41,"tag":523,"props":1350,"children":1351},{"style":552},[1352],{"type":46,"value":1353}," ctx",{"type":41,"tag":523,"props":1355,"children":1356},{"style":546},[1357],{"type":46,"value":265},{"type":41,"tag":523,"props":1359,"children":1360},{"style":552},[1361],{"type":46,"value":1362},"db",{"type":41,"tag":523,"props":1364,"children":1365},{"style":546},[1366],{"type":46,"value":265},{"type":41,"tag":523,"props":1368,"children":1369},{"style":613},[1370],{"type":46,"value":1371},"insert",{"type":41,"tag":523,"props":1373,"children":1374},{"style":787},[1375],{"type":46,"value":620},{"type":41,"tag":523,"props":1377,"children":1378},{"style":546},[1379],{"type":46,"value":581},{"type":41,"tag":523,"props":1381,"children":1382},{"style":573},[1383],{"type":46,"value":629},{"type":41,"tag":523,"props":1385,"children":1386},{"style":546},[1387],{"type":46,"value":581},{"type":41,"tag":523,"props":1389,"children":1390},{"style":546},[1391],{"type":46,"value":678},{"type":41,"tag":523,"props":1393,"children":1394},{"style":546},[1395],{"type":46,"value":1335},{"type":41,"tag":523,"props":1397,"children":1398},{"class":525,"line":912},[1399,1404,1408,1412,1416,1420],{"type":41,"tag":523,"props":1400,"children":1401},{"style":787},[1402],{"type":46,"value":1403},"      userId",{"type":41,"tag":523,"props":1405,"children":1406},{"style":546},[1407],{"type":46,"value":795},{"type":41,"tag":523,"props":1409,"children":1410},{"style":552},[1411],{"type":46,"value":1321},{"type":41,"tag":523,"props":1413,"children":1414},{"style":546},[1415],{"type":46,"value":265},{"type":41,"tag":523,"props":1417,"children":1418},{"style":552},[1419],{"type":46,"value":966},{"type":41,"tag":523,"props":1421,"children":1422},{"style":546},[1423],{"type":46,"value":842},{"type":41,"tag":523,"props":1425,"children":1426},{"class":525,"line":999},[1427,1432,1436,1440,1444,1449],{"type":41,"tag":523,"props":1428,"children":1429},{"style":787},[1430],{"type":46,"value":1431},"      message",{"type":41,"tag":523,"props":1433,"children":1434},{"style":546},[1435],{"type":46,"value":795},{"type":41,"tag":523,"props":1437,"children":1438},{"style":552},[1439],{"type":46,"value":1321},{"type":41,"tag":523,"props":1441,"children":1442},{"style":546},[1443],{"type":46,"value":265},{"type":41,"tag":523,"props":1445,"children":1446},{"style":552},[1447],{"type":46,"value":1448},"message",{"type":41,"tag":523,"props":1450,"children":1451},{"style":546},[1452],{"type":46,"value":842},{"type":41,"tag":523,"props":1454,"children":1456},{"class":525,"line":1455},12,[1457,1462,1466,1472],{"type":41,"tag":523,"props":1458,"children":1459},{"style":787},[1460],{"type":46,"value":1461},"      read",{"type":41,"tag":523,"props":1463,"children":1464},{"style":546},[1465],{"type":46,"value":795},{"type":41,"tag":523,"props":1467,"children":1469},{"style":1468},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[1470],{"type":46,"value":1471}," false",{"type":41,"tag":523,"props":1473,"children":1474},{"style":546},[1475],{"type":46,"value":842},{"type":41,"tag":523,"props":1477,"children":1479},{"class":525,"line":1478},13,[1480,1485,1489],{"type":41,"tag":523,"props":1481,"children":1482},{"style":546},[1483],{"type":46,"value":1484},"    }",{"type":41,"tag":523,"props":1486,"children":1487},{"style":787},[1488],{"type":46,"value":638},{"type":41,"tag":523,"props":1490,"children":1491},{"style":546},[1492],{"type":46,"value":586},{"type":41,"tag":523,"props":1494,"children":1496},{"class":525,"line":1495},14,[1497],{"type":41,"tag":523,"props":1498,"children":1499},{"style":546},[1500],{"type":46,"value":1501},"  },\n",{"type":41,"tag":523,"props":1503,"children":1505},{"class":525,"line":1504},15,[1506,1510,1514],{"type":41,"tag":523,"props":1507,"children":1508},{"style":546},[1509],{"type":46,"value":1005},{"type":41,"tag":523,"props":1511,"children":1512},{"style":552},[1513],{"type":46,"value":638},{"type":41,"tag":523,"props":1515,"children":1516},{"style":546},[1517],{"type":46,"value":586},{"type":41,"tag":523,"props":1519,"children":1521},{"class":525,"line":1520},16,[1522],{"type":41,"tag":523,"props":1523,"children":1524},{"emptyLinePlaceholder":593},[1525],{"type":46,"value":596},{"type":41,"tag":523,"props":1527,"children":1529},{"class":525,"line":1528},17,[1530,1534,1538,1543,1547,1551,1555],{"type":41,"tag":523,"props":1531,"children":1532},{"style":540},[1533],{"type":46,"value":605},{"type":41,"tag":523,"props":1535,"children":1536},{"style":1134},[1537],{"type":46,"value":1137},{"type":41,"tag":523,"props":1539,"children":1540},{"style":552},[1541],{"type":46,"value":1542}," listUnread ",{"type":41,"tag":523,"props":1544,"children":1545},{"style":546},[1546],{"type":46,"value":1147},{"type":41,"tag":523,"props":1548,"children":1549},{"style":613},[1550],{"type":46,"value":1092},{"type":41,"tag":523,"props":1552,"children":1553},{"style":552},[1554],{"type":46,"value":620},{"type":41,"tag":523,"props":1556,"children":1557},{"style":546},[1558],{"type":46,"value":780},{"type":41,"tag":523,"props":1560,"children":1562},{"class":525,"line":1561},18,[1563,1567,1571,1575,1579,1583,1587,1591,1595,1599],{"type":41,"tag":523,"props":1564,"children":1565},{"style":787},[1566],{"type":46,"value":1167},{"type":41,"tag":523,"props":1568,"children":1569},{"style":546},[1570],{"type":46,"value":795},{"type":41,"tag":523,"props":1572,"children":1573},{"style":546},[1574],{"type":46,"value":549},{"type":41,"tag":523,"props":1576,"children":1577},{"style":787},[1578],{"type":46,"value":1180},{"type":41,"tag":523,"props":1580,"children":1581},{"style":546},[1582],{"type":46,"value":795},{"type":41,"tag":523,"props":1584,"children":1585},{"style":552},[1586],{"type":46,"value":723},{"type":41,"tag":523,"props":1588,"children":1589},{"style":546},[1590],{"type":46,"value":265},{"type":41,"tag":523,"props":1592,"children":1593},{"style":613},[1594],{"type":46,"value":832},{"type":41,"tag":523,"props":1596,"children":1597},{"style":552},[1598],{"type":46,"value":1230},{"type":41,"tag":523,"props":1600,"children":1601},{"style":546},[1602],{"type":46,"value":1235},{"type":41,"tag":523,"props":1604,"children":1606},{"class":525,"line":1605},19,[1607,1611,1615,1619,1623,1628],{"type":41,"tag":523,"props":1608,"children":1609},{"style":787},[1610],{"type":46,"value":1243},{"type":41,"tag":523,"props":1612,"children":1613},{"style":546},[1614],{"type":46,"value":795},{"type":41,"tag":523,"props":1616,"children":1617},{"style":552},[1618],{"type":46,"value":723},{"type":41,"tag":523,"props":1620,"children":1621},{"style":546},[1622],{"type":46,"value":265},{"type":41,"tag":523,"props":1624,"children":1625},{"style":613},[1626],{"type":46,"value":1627},"array",{"type":41,"tag":523,"props":1629,"children":1630},{"style":552},[1631],{"type":46,"value":1632},"(\n",{"type":41,"tag":523,"props":1634,"children":1636},{"class":525,"line":1635},20,[1637,1642,1646,1651,1655],{"type":41,"tag":523,"props":1638,"children":1639},{"style":552},[1640],{"type":46,"value":1641},"    v",{"type":41,"tag":523,"props":1643,"children":1644},{"style":546},[1645],{"type":46,"value":265},{"type":41,"tag":523,"props":1647,"children":1648},{"style":613},[1649],{"type":46,"value":1650},"object",{"type":41,"tag":523,"props":1652,"children":1653},{"style":552},[1654],{"type":46,"value":620},{"type":41,"tag":523,"props":1656,"children":1657},{"style":546},[1658],{"type":46,"value":780},{"type":41,"tag":523,"props":1660,"children":1662},{"class":525,"line":1661},21,[1663,1668,1672,1676,1680,1684,1688,1692,1696,1700,1704],{"type":41,"tag":523,"props":1664,"children":1665},{"style":787},[1666],{"type":46,"value":1667},"      _id",{"type":41,"tag":523,"props":1669,"children":1670},{"style":546},[1671],{"type":46,"value":795},{"type":41,"tag":523,"props":1673,"children":1674},{"style":552},[1675],{"type":46,"value":723},{"type":41,"tag":523,"props":1677,"children":1678},{"style":546},[1679],{"type":46,"value":265},{"type":41,"tag":523,"props":1681,"children":1682},{"style":613},[1683],{"type":46,"value":1260},{"type":41,"tag":523,"props":1685,"children":1686},{"style":552},[1687],{"type":46,"value":620},{"type":41,"tag":523,"props":1689,"children":1690},{"style":546},[1691],{"type":46,"value":581},{"type":41,"tag":523,"props":1693,"children":1694},{"style":573},[1695],{"type":46,"value":629},{"type":41,"tag":523,"props":1697,"children":1698},{"style":546},[1699],{"type":46,"value":581},{"type":41,"tag":523,"props":1701,"children":1702},{"style":552},[1703],{"type":46,"value":638},{"type":41,"tag":523,"props":1705,"children":1706},{"style":546},[1707],{"type":46,"value":842},{"type":41,"tag":523,"props":1709,"children":1711},{"class":525,"line":1710},22,[1712,1717,1721,1725,1729,1734,1738],{"type":41,"tag":523,"props":1713,"children":1714},{"style":787},[1715],{"type":46,"value":1716},"      _creationTime",{"type":41,"tag":523,"props":1718,"children":1719},{"style":546},[1720],{"type":46,"value":795},{"type":41,"tag":523,"props":1722,"children":1723},{"style":552},[1724],{"type":46,"value":723},{"type":41,"tag":523,"props":1726,"children":1727},{"style":546},[1728],{"type":46,"value":265},{"type":41,"tag":523,"props":1730,"children":1731},{"style":613},[1732],{"type":46,"value":1733},"number",{"type":41,"tag":523,"props":1735,"children":1736},{"style":552},[1737],{"type":46,"value":837},{"type":41,"tag":523,"props":1739,"children":1740},{"style":546},[1741],{"type":46,"value":842},{"type":41,"tag":523,"props":1743,"children":1745},{"class":525,"line":1744},23,[1746,1750,1754,1758,1762,1766,1770],{"type":41,"tag":523,"props":1747,"children":1748},{"style":787},[1749],{"type":46,"value":1403},{"type":41,"tag":523,"props":1751,"children":1752},{"style":546},[1753],{"type":46,"value":795},{"type":41,"tag":523,"props":1755,"children":1756},{"style":552},[1757],{"type":46,"value":723},{"type":41,"tag":523,"props":1759,"children":1760},{"style":546},[1761],{"type":46,"value":265},{"type":41,"tag":523,"props":1763,"children":1764},{"style":613},[1765],{"type":46,"value":832},{"type":41,"tag":523,"props":1767,"children":1768},{"style":552},[1769],{"type":46,"value":837},{"type":41,"tag":523,"props":1771,"children":1772},{"style":546},[1773],{"type":46,"value":842},{"type":41,"tag":523,"props":1775,"children":1777},{"class":525,"line":1776},24,[1778,1782,1786,1790,1794,1798,1802],{"type":41,"tag":523,"props":1779,"children":1780},{"style":787},[1781],{"type":46,"value":1431},{"type":41,"tag":523,"props":1783,"children":1784},{"style":546},[1785],{"type":46,"value":795},{"type":41,"tag":523,"props":1787,"children":1788},{"style":552},[1789],{"type":46,"value":723},{"type":41,"tag":523,"props":1791,"children":1792},{"style":546},[1793],{"type":46,"value":265},{"type":41,"tag":523,"props":1795,"children":1796},{"style":613},[1797],{"type":46,"value":832},{"type":41,"tag":523,"props":1799,"children":1800},{"style":552},[1801],{"type":46,"value":837},{"type":41,"tag":523,"props":1803,"children":1804},{"style":546},[1805],{"type":46,"value":842},{"type":41,"tag":523,"props":1807,"children":1809},{"class":525,"line":1808},25,[1810,1814,1818,1822,1826,1830,1834],{"type":41,"tag":523,"props":1811,"children":1812},{"style":787},[1813],{"type":46,"value":1461},{"type":41,"tag":523,"props":1815,"children":1816},{"style":546},[1817],{"type":46,"value":795},{"type":41,"tag":523,"props":1819,"children":1820},{"style":552},[1821],{"type":46,"value":723},{"type":41,"tag":523,"props":1823,"children":1824},{"style":546},[1825],{"type":46,"value":265},{"type":41,"tag":523,"props":1827,"children":1828},{"style":613},[1829],{"type":46,"value":901},{"type":41,"tag":523,"props":1831,"children":1832},{"style":552},[1833],{"type":46,"value":837},{"type":41,"tag":523,"props":1835,"children":1836},{"style":546},[1837],{"type":46,"value":842},{"type":41,"tag":523,"props":1839,"children":1841},{"class":525,"line":1840},26,[1842,1846,1850],{"type":41,"tag":523,"props":1843,"children":1844},{"style":546},[1845],{"type":46,"value":1484},{"type":41,"tag":523,"props":1847,"children":1848},{"style":552},[1849],{"type":46,"value":638},{"type":41,"tag":523,"props":1851,"children":1852},{"style":546},[1853],{"type":46,"value":842},{"type":41,"tag":523,"props":1855,"children":1857},{"class":525,"line":1856},27,[1858,1863],{"type":41,"tag":523,"props":1859,"children":1860},{"style":552},[1861],{"type":46,"value":1862},"  )",{"type":41,"tag":523,"props":1864,"children":1865},{"style":546},[1866],{"type":46,"value":842},{"type":41,"tag":523,"props":1868,"children":1870},{"class":525,"line":1869},28,[1871,1875,1879,1883,1887,1891,1895,1899,1903,1907],{"type":41,"tag":523,"props":1872,"children":1873},{"style":613},[1874],{"type":46,"value":1292},{"type":41,"tag":523,"props":1876,"children":1877},{"style":546},[1878],{"type":46,"value":795},{"type":41,"tag":523,"props":1880,"children":1881},{"style":1134},[1882],{"type":46,"value":1301},{"type":41,"tag":523,"props":1884,"children":1885},{"style":546},[1886],{"type":46,"value":1306},{"type":41,"tag":523,"props":1888,"children":1889},{"style":1309},[1890],{"type":46,"value":1312},{"type":41,"tag":523,"props":1892,"children":1893},{"style":546},[1894],{"type":46,"value":678},{"type":41,"tag":523,"props":1896,"children":1897},{"style":1309},[1898],{"type":46,"value":1321},{"type":41,"tag":523,"props":1900,"children":1901},{"style":546},[1902],{"type":46,"value":638},{"type":41,"tag":523,"props":1904,"children":1905},{"style":1134},[1906],{"type":46,"value":1330},{"type":41,"tag":523,"props":1908,"children":1909},{"style":546},[1910],{"type":46,"value":1335},{"type":41,"tag":523,"props":1912,"children":1914},{"class":525,"line":1913},29,[1915,1919,1923,1927,1931],{"type":41,"tag":523,"props":1916,"children":1917},{"style":540},[1918],{"type":46,"value":1343},{"type":41,"tag":523,"props":1920,"children":1921},{"style":540},[1922],{"type":46,"value":1348},{"type":41,"tag":523,"props":1924,"children":1925},{"style":552},[1926],{"type":46,"value":1353},{"type":41,"tag":523,"props":1928,"children":1929},{"style":546},[1930],{"type":46,"value":265},{"type":41,"tag":523,"props":1932,"children":1933},{"style":552},[1934],{"type":46,"value":1935},"db\n",{"type":41,"tag":523,"props":1937,"children":1939},{"class":525,"line":1938},30,[1940,1945,1950,1954,1958,1962,1966],{"type":41,"tag":523,"props":1941,"children":1942},{"style":546},[1943],{"type":46,"value":1944},"      .",{"type":41,"tag":523,"props":1946,"children":1947},{"style":613},[1948],{"type":46,"value":1949},"query",{"type":41,"tag":523,"props":1951,"children":1952},{"style":787},[1953],{"type":46,"value":620},{"type":41,"tag":523,"props":1955,"children":1956},{"style":546},[1957],{"type":46,"value":581},{"type":41,"tag":523,"props":1959,"children":1960},{"style":573},[1961],{"type":46,"value":629},{"type":41,"tag":523,"props":1963,"children":1964},{"style":546},[1965],{"type":46,"value":581},{"type":41,"tag":523,"props":1967,"children":1968},{"style":787},[1969],{"type":46,"value":1970},")\n",{"type":41,"tag":523,"props":1972,"children":1974},{"class":525,"line":1973},31,[1975,1979,1984,1988,1992,1996,2000,2004,2008,2013,2017],{"type":41,"tag":523,"props":1976,"children":1977},{"style":546},[1978],{"type":46,"value":1944},{"type":41,"tag":523,"props":1980,"children":1981},{"style":613},[1982],{"type":46,"value":1983},"withIndex",{"type":41,"tag":523,"props":1985,"children":1986},{"style":787},[1987],{"type":46,"value":620},{"type":41,"tag":523,"props":1989,"children":1990},{"style":546},[1991],{"type":46,"value":581},{"type":41,"tag":523,"props":1993,"children":1994},{"style":573},[1995],{"type":46,"value":944},{"type":41,"tag":523,"props":1997,"children":1998},{"style":546},[1999],{"type":46,"value":581},{"type":41,"tag":523,"props":2001,"children":2002},{"style":546},[2003],{"type":46,"value":678},{"type":41,"tag":523,"props":2005,"children":2006},{"style":546},[2007],{"type":46,"value":1306},{"type":41,"tag":523,"props":2009,"children":2010},{"style":1309},[2011],{"type":46,"value":2012},"q",{"type":41,"tag":523,"props":2014,"children":2015},{"style":546},[2016],{"type":46,"value":638},{"type":41,"tag":523,"props":2018,"children":2019},{"style":1134},[2020],{"type":46,"value":2021}," =>\n",{"type":41,"tag":523,"props":2023,"children":2025},{"class":525,"line":2024},32,[2026,2031,2035,2040,2044,2048,2052,2056,2060,2064,2068,2072,2076,2080,2084,2088,2092,2096,2100,2104,2108,2112],{"type":41,"tag":523,"props":2027,"children":2028},{"style":552},[2029],{"type":46,"value":2030},"        q",{"type":41,"tag":523,"props":2032,"children":2033},{"style":546},[2034],{"type":46,"value":265},{"type":41,"tag":523,"props":2036,"children":2037},{"style":613},[2038],{"type":46,"value":2039},"eq",{"type":41,"tag":523,"props":2041,"children":2042},{"style":787},[2043],{"type":46,"value":620},{"type":41,"tag":523,"props":2045,"children":2046},{"style":546},[2047],{"type":46,"value":581},{"type":41,"tag":523,"props":2049,"children":2050},{"style":573},[2051],{"type":46,"value":966},{"type":41,"tag":523,"props":2053,"children":2054},{"style":546},[2055],{"type":46,"value":581},{"type":41,"tag":523,"props":2057,"children":2058},{"style":546},[2059],{"type":46,"value":678},{"type":41,"tag":523,"props":2061,"children":2062},{"style":552},[2063],{"type":46,"value":1321},{"type":41,"tag":523,"props":2065,"children":2066},{"style":546},[2067],{"type":46,"value":265},{"type":41,"tag":523,"props":2069,"children":2070},{"style":552},[2071],{"type":46,"value":966},{"type":41,"tag":523,"props":2073,"children":2074},{"style":787},[2075],{"type":46,"value":638},{"type":41,"tag":523,"props":2077,"children":2078},{"style":546},[2079],{"type":46,"value":265},{"type":41,"tag":523,"props":2081,"children":2082},{"style":613},[2083],{"type":46,"value":2039},{"type":41,"tag":523,"props":2085,"children":2086},{"style":787},[2087],{"type":46,"value":620},{"type":41,"tag":523,"props":2089,"children":2090},{"style":546},[2091],{"type":46,"value":581},{"type":41,"tag":523,"props":2093,"children":2094},{"style":573},[2095],{"type":46,"value":983},{"type":41,"tag":523,"props":2097,"children":2098},{"style":546},[2099],{"type":46,"value":581},{"type":41,"tag":523,"props":2101,"children":2102},{"style":546},[2103],{"type":46,"value":678},{"type":41,"tag":523,"props":2105,"children":2106},{"style":1468},[2107],{"type":46,"value":1471},{"type":41,"tag":523,"props":2109,"children":2110},{"style":787},[2111],{"type":46,"value":638},{"type":41,"tag":523,"props":2113,"children":2114},{"style":546},[2115],{"type":46,"value":842},{"type":41,"tag":523,"props":2117,"children":2119},{"class":525,"line":2118},33,[2120],{"type":41,"tag":523,"props":2121,"children":2122},{"style":787},[2123],{"type":46,"value":2124},"      )\n",{"type":41,"tag":523,"props":2126,"children":2127},{"class":525,"line":24},[2128,2132,2137,2141],{"type":41,"tag":523,"props":2129,"children":2130},{"style":546},[2131],{"type":46,"value":1944},{"type":41,"tag":523,"props":2133,"children":2134},{"style":613},[2135],{"type":46,"value":2136},"collect",{"type":41,"tag":523,"props":2138,"children":2139},{"style":787},[2140],{"type":46,"value":837},{"type":41,"tag":523,"props":2142,"children":2143},{"style":546},[2144],{"type":46,"value":586},{"type":41,"tag":523,"props":2146,"children":2148},{"class":525,"line":2147},35,[2149],{"type":41,"tag":523,"props":2150,"children":2151},{"style":546},[2152],{"type":46,"value":1501},{"type":41,"tag":523,"props":2154,"children":2156},{"class":525,"line":2155},36,[2157,2161,2165],{"type":41,"tag":523,"props":2158,"children":2159},{"style":546},[2160],{"type":46,"value":1005},{"type":41,"tag":523,"props":2162,"children":2163},{"style":552},[2164],{"type":46,"value":638},{"type":41,"tag":523,"props":2166,"children":2167},{"style":546},[2168],{"type":46,"value":586},{"type":41,"tag":512,"props":2170,"children":2172},{"className":514,"code":2171,"language":516,"meta":517,"style":517},"\u002F\u002F convex\u002Fconvex.config.ts\nimport { defineApp } from \"convex\u002Fserver\";\nimport notifications from \".\u002Fcomponents\u002Fnotifications\u002Fconvex.config.js\";\n\nconst app = defineApp();\napp.use(notifications);\n\nexport default app;\n",[2173],{"type":41,"tag":111,"props":2174,"children":2175},{"__ignoreMap":517},[2176,2184,2224,2258,2265,2294,2320,2327],{"type":41,"tag":523,"props":2177,"children":2178},{"class":525,"line":526},[2179],{"type":41,"tag":523,"props":2180,"children":2181},{"style":530},[2182],{"type":46,"value":2183},"\u002F\u002F convex\u002Fconvex.config.ts\n",{"type":41,"tag":523,"props":2185,"children":2186},{"class":525,"line":536},[2187,2191,2195,2200,2204,2208,2212,2216,2220],{"type":41,"tag":523,"props":2188,"children":2189},{"style":540},[2190],{"type":46,"value":543},{"type":41,"tag":523,"props":2192,"children":2193},{"style":546},[2194],{"type":46,"value":549},{"type":41,"tag":523,"props":2196,"children":2197},{"style":552},[2198],{"type":46,"value":2199}," defineApp",{"type":41,"tag":523,"props":2201,"children":2202},{"style":546},[2203],{"type":46,"value":560},{"type":41,"tag":523,"props":2205,"children":2206},{"style":540},[2207],{"type":46,"value":565},{"type":41,"tag":523,"props":2209,"children":2210},{"style":546},[2211],{"type":46,"value":570},{"type":41,"tag":523,"props":2213,"children":2214},{"style":573},[2215],{"type":46,"value":576},{"type":41,"tag":523,"props":2217,"children":2218},{"style":546},[2219],{"type":46,"value":581},{"type":41,"tag":523,"props":2221,"children":2222},{"style":546},[2223],{"type":46,"value":586},{"type":41,"tag":523,"props":2225,"children":2226},{"class":525,"line":589},[2227,2231,2236,2241,2245,2250,2254],{"type":41,"tag":523,"props":2228,"children":2229},{"style":540},[2230],{"type":46,"value":543},{"type":41,"tag":523,"props":2232,"children":2233},{"style":552},[2234],{"type":46,"value":2235}," notifications ",{"type":41,"tag":523,"props":2237,"children":2238},{"style":540},[2239],{"type":46,"value":2240},"from",{"type":41,"tag":523,"props":2242,"children":2243},{"style":546},[2244],{"type":46,"value":570},{"type":41,"tag":523,"props":2246,"children":2247},{"style":573},[2248],{"type":46,"value":2249},".\u002Fcomponents\u002Fnotifications\u002Fconvex.config.js",{"type":41,"tag":523,"props":2251,"children":2252},{"style":546},[2253],{"type":46,"value":581},{"type":41,"tag":523,"props":2255,"children":2256},{"style":546},[2257],{"type":46,"value":586},{"type":41,"tag":523,"props":2259,"children":2260},{"class":525,"line":599},[2261],{"type":41,"tag":523,"props":2262,"children":2263},{"emptyLinePlaceholder":593},[2264],{"type":46,"value":596},{"type":41,"tag":523,"props":2266,"children":2267},{"class":525,"line":758},[2268,2273,2278,2282,2286,2290],{"type":41,"tag":523,"props":2269,"children":2270},{"style":1134},[2271],{"type":46,"value":2272},"const",{"type":41,"tag":523,"props":2274,"children":2275},{"style":552},[2276],{"type":46,"value":2277}," app ",{"type":41,"tag":523,"props":2279,"children":2280},{"style":546},[2281],{"type":46,"value":1147},{"type":41,"tag":523,"props":2283,"children":2284},{"style":613},[2285],{"type":46,"value":2199},{"type":41,"tag":523,"props":2287,"children":2288},{"style":552},[2289],{"type":46,"value":837},{"type":41,"tag":523,"props":2291,"children":2292},{"style":546},[2293],{"type":46,"value":586},{"type":41,"tag":523,"props":2295,"children":2296},{"class":525,"line":783},[2297,2302,2306,2311,2316],{"type":41,"tag":523,"props":2298,"children":2299},{"style":552},[2300],{"type":46,"value":2301},"app",{"type":41,"tag":523,"props":2303,"children":2304},{"style":546},[2305],{"type":46,"value":265},{"type":41,"tag":523,"props":2307,"children":2308},{"style":613},[2309],{"type":46,"value":2310},"use",{"type":41,"tag":523,"props":2312,"children":2313},{"style":552},[2314],{"type":46,"value":2315},"(notifications)",{"type":41,"tag":523,"props":2317,"children":2318},{"style":546},[2319],{"type":46,"value":586},{"type":41,"tag":523,"props":2321,"children":2322},{"class":525,"line":28},[2323],{"type":41,"tag":523,"props":2324,"children":2325},{"emptyLinePlaceholder":593},[2326],{"type":46,"value":596},{"type":41,"tag":523,"props":2328,"children":2329},{"class":525,"line":845},[2330,2334,2338,2343],{"type":41,"tag":523,"props":2331,"children":2332},{"style":540},[2333],{"type":46,"value":605},{"type":41,"tag":523,"props":2335,"children":2336},{"style":540},[2337],{"type":46,"value":610},{"type":41,"tag":523,"props":2339,"children":2340},{"style":552},[2341],{"type":46,"value":2342}," app",{"type":41,"tag":523,"props":2344,"children":2345},{"style":546},[2346],{"type":46,"value":586},{"type":41,"tag":512,"props":2348,"children":2350},{"className":514,"code":2349,"language":516,"meta":517,"style":517},"\u002F\u002F convex\u002Fnotifications.ts  (app-side wrapper)\nimport { v } from \"convex\u002Fvalues\";\nimport { mutation, query } from \".\u002F_generated\u002Fserver\";\nimport { components } from \".\u002F_generated\u002Fapi\";\nimport { getAuthUserId } from \"@convex-dev\u002Fauth\u002Fserver\";\n\nexport const sendNotification = mutation({\n  args: { message: v.string() },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    const userId = await getAuthUserId(ctx);\n    if (!userId) throw new Error(\"Not authenticated\");\n\n    await ctx.runMutation(components.notifications.lib.send, {\n      userId,\n      message: args.message,\n    });\n    return null;\n  },\n});\n\nexport const myUnread = query({\n  args: {},\n  handler: async (ctx) => {\n    const userId = await getAuthUserId(ctx);\n    if (!userId) throw new Error(\"Not authenticated\");\n\n    return await ctx.runQuery(components.notifications.lib.listUnread, {\n      userId,\n    });\n  },\n});\n",[2351],{"type":41,"tag":111,"props":2352,"children":2353},{"__ignoreMap":517},[2354,2362,2401,2448,2489,2530,2537,2569,2612,2644,2687,2728,2794,2801,2865,2876,2903,2918,2930,2937,2952,2959,2991,3007,3042,3081,3140,3147,3212,3223,3238,3245],{"type":41,"tag":523,"props":2355,"children":2356},{"class":525,"line":526},[2357],{"type":41,"tag":523,"props":2358,"children":2359},{"style":530},[2360],{"type":46,"value":2361},"\u002F\u002F convex\u002Fnotifications.ts  (app-side wrapper)\n",{"type":41,"tag":523,"props":2363,"children":2364},{"class":525,"line":536},[2365,2369,2373,2377,2381,2385,2389,2393,2397],{"type":41,"tag":523,"props":2366,"children":2367},{"style":540},[2368],{"type":46,"value":543},{"type":41,"tag":523,"props":2370,"children":2371},{"style":546},[2372],{"type":46,"value":549},{"type":41,"tag":523,"props":2374,"children":2375},{"style":552},[2376],{"type":46,"value":723},{"type":41,"tag":523,"props":2378,"children":2379},{"style":546},[2380],{"type":46,"value":560},{"type":41,"tag":523,"props":2382,"children":2383},{"style":540},[2384],{"type":46,"value":565},{"type":41,"tag":523,"props":2386,"children":2387},{"style":546},[2388],{"type":46,"value":570},{"type":41,"tag":523,"props":2390,"children":2391},{"style":573},[2392],{"type":46,"value":740},{"type":41,"tag":523,"props":2394,"children":2395},{"style":546},[2396],{"type":46,"value":581},{"type":41,"tag":523,"props":2398,"children":2399},{"style":546},[2400],{"type":46,"value":586},{"type":41,"tag":523,"props":2402,"children":2403},{"class":525,"line":589},[2404,2408,2412,2416,2420,2424,2428,2432,2436,2440,2444],{"type":41,"tag":523,"props":2405,"children":2406},{"style":540},[2407],{"type":46,"value":543},{"type":41,"tag":523,"props":2409,"children":2410},{"style":546},[2411],{"type":46,"value":549},{"type":41,"tag":523,"props":2413,"children":2414},{"style":552},[2415],{"type":46,"value":1083},{"type":41,"tag":523,"props":2417,"children":2418},{"style":546},[2419],{"type":46,"value":678},{"type":41,"tag":523,"props":2421,"children":2422},{"style":552},[2423],{"type":46,"value":1092},{"type":41,"tag":523,"props":2425,"children":2426},{"style":546},[2427],{"type":46,"value":560},{"type":41,"tag":523,"props":2429,"children":2430},{"style":540},[2431],{"type":46,"value":565},{"type":41,"tag":523,"props":2433,"children":2434},{"style":546},[2435],{"type":46,"value":570},{"type":41,"tag":523,"props":2437,"children":2438},{"style":573},[2439],{"type":46,"value":206},{"type":41,"tag":523,"props":2441,"children":2442},{"style":546},[2443],{"type":46,"value":581},{"type":41,"tag":523,"props":2445,"children":2446},{"style":546},[2447],{"type":46,"value":586},{"type":41,"tag":523,"props":2449,"children":2450},{"class":525,"line":599},[2451,2455,2459,2464,2468,2472,2476,2481,2485],{"type":41,"tag":523,"props":2452,"children":2453},{"style":540},[2454],{"type":46,"value":543},{"type":41,"tag":523,"props":2456,"children":2457},{"style":546},[2458],{"type":46,"value":549},{"type":41,"tag":523,"props":2460,"children":2461},{"style":552},[2462],{"type":46,"value":2463}," components",{"type":41,"tag":523,"props":2465,"children":2466},{"style":546},[2467],{"type":46,"value":560},{"type":41,"tag":523,"props":2469,"children":2470},{"style":540},[2471],{"type":46,"value":565},{"type":41,"tag":523,"props":2473,"children":2474},{"style":546},[2475],{"type":46,"value":570},{"type":41,"tag":523,"props":2477,"children":2478},{"style":573},[2479],{"type":46,"value":2480},".\u002F_generated\u002Fapi",{"type":41,"tag":523,"props":2482,"children":2483},{"style":546},[2484],{"type":46,"value":581},{"type":41,"tag":523,"props":2486,"children":2487},{"style":546},[2488],{"type":46,"value":586},{"type":41,"tag":523,"props":2490,"children":2491},{"class":525,"line":758},[2492,2496,2500,2505,2509,2513,2517,2522,2526],{"type":41,"tag":523,"props":2493,"children":2494},{"style":540},[2495],{"type":46,"value":543},{"type":41,"tag":523,"props":2497,"children":2498},{"style":546},[2499],{"type":46,"value":549},{"type":41,"tag":523,"props":2501,"children":2502},{"style":552},[2503],{"type":46,"value":2504}," getAuthUserId",{"type":41,"tag":523,"props":2506,"children":2507},{"style":546},[2508],{"type":46,"value":560},{"type":41,"tag":523,"props":2510,"children":2511},{"style":540},[2512],{"type":46,"value":565},{"type":41,"tag":523,"props":2514,"children":2515},{"style":546},[2516],{"type":46,"value":570},{"type":41,"tag":523,"props":2518,"children":2519},{"style":573},[2520],{"type":46,"value":2521},"@convex-dev\u002Fauth\u002Fserver",{"type":41,"tag":523,"props":2523,"children":2524},{"style":546},[2525],{"type":46,"value":581},{"type":41,"tag":523,"props":2527,"children":2528},{"style":546},[2529],{"type":46,"value":586},{"type":41,"tag":523,"props":2531,"children":2532},{"class":525,"line":783},[2533],{"type":41,"tag":523,"props":2534,"children":2535},{"emptyLinePlaceholder":593},[2536],{"type":46,"value":596},{"type":41,"tag":523,"props":2538,"children":2539},{"class":525,"line":28},[2540,2544,2548,2553,2557,2561,2565],{"type":41,"tag":523,"props":2541,"children":2542},{"style":540},[2543],{"type":46,"value":605},{"type":41,"tag":523,"props":2545,"children":2546},{"style":1134},[2547],{"type":46,"value":1137},{"type":41,"tag":523,"props":2549,"children":2550},{"style":552},[2551],{"type":46,"value":2552}," sendNotification ",{"type":41,"tag":523,"props":2554,"children":2555},{"style":546},[2556],{"type":46,"value":1147},{"type":41,"tag":523,"props":2558,"children":2559},{"style":613},[2560],{"type":46,"value":1083},{"type":41,"tag":523,"props":2562,"children":2563},{"style":552},[2564],{"type":46,"value":620},{"type":41,"tag":523,"props":2566,"children":2567},{"style":546},[2568],{"type":46,"value":780},{"type":41,"tag":523,"props":2570,"children":2571},{"class":525,"line":845},[2572,2576,2580,2584,2588,2592,2596,2600,2604,2608],{"type":41,"tag":523,"props":2573,"children":2574},{"style":787},[2575],{"type":46,"value":1167},{"type":41,"tag":523,"props":2577,"children":2578},{"style":546},[2579],{"type":46,"value":795},{"type":41,"tag":523,"props":2581,"children":2582},{"style":546},[2583],{"type":46,"value":549},{"type":41,"tag":523,"props":2585,"children":2586},{"style":787},[2587],{"type":46,"value":1209},{"type":41,"tag":523,"props":2589,"children":2590},{"style":546},[2591],{"type":46,"value":795},{"type":41,"tag":523,"props":2593,"children":2594},{"style":552},[2595],{"type":46,"value":723},{"type":41,"tag":523,"props":2597,"children":2598},{"style":546},[2599],{"type":46,"value":265},{"type":41,"tag":523,"props":2601,"children":2602},{"style":613},[2603],{"type":46,"value":832},{"type":41,"tag":523,"props":2605,"children":2606},{"style":552},[2607],{"type":46,"value":1230},{"type":41,"tag":523,"props":2609,"children":2610},{"style":546},[2611],{"type":46,"value":1235},{"type":41,"tag":523,"props":2613,"children":2614},{"class":525,"line":878},[2615,2619,2623,2627,2631,2636,2640],{"type":41,"tag":523,"props":2616,"children":2617},{"style":787},[2618],{"type":46,"value":1243},{"type":41,"tag":523,"props":2620,"children":2621},{"style":546},[2622],{"type":46,"value":795},{"type":41,"tag":523,"props":2624,"children":2625},{"style":552},[2626],{"type":46,"value":723},{"type":41,"tag":523,"props":2628,"children":2629},{"style":546},[2630],{"type":46,"value":265},{"type":41,"tag":523,"props":2632,"children":2633},{"style":613},[2634],{"type":46,"value":2635},"null",{"type":41,"tag":523,"props":2637,"children":2638},{"style":552},[2639],{"type":46,"value":837},{"type":41,"tag":523,"props":2641,"children":2642},{"style":546},[2643],{"type":46,"value":842},{"type":41,"tag":523,"props":2645,"children":2646},{"class":525,"line":912},[2647,2651,2655,2659,2663,2667,2671,2675,2679,2683],{"type":41,"tag":523,"props":2648,"children":2649},{"style":613},[2650],{"type":46,"value":1292},{"type":41,"tag":523,"props":2652,"children":2653},{"style":546},[2654],{"type":46,"value":795},{"type":41,"tag":523,"props":2656,"children":2657},{"style":1134},[2658],{"type":46,"value":1301},{"type":41,"tag":523,"props":2660,"children":2661},{"style":546},[2662],{"type":46,"value":1306},{"type":41,"tag":523,"props":2664,"children":2665},{"style":1309},[2666],{"type":46,"value":1312},{"type":41,"tag":523,"props":2668,"children":2669},{"style":546},[2670],{"type":46,"value":678},{"type":41,"tag":523,"props":2672,"children":2673},{"style":1309},[2674],{"type":46,"value":1321},{"type":41,"tag":523,"props":2676,"children":2677},{"style":546},[2678],{"type":46,"value":638},{"type":41,"tag":523,"props":2680,"children":2681},{"style":1134},[2682],{"type":46,"value":1330},{"type":41,"tag":523,"props":2684,"children":2685},{"style":546},[2686],{"type":46,"value":1335},{"type":41,"tag":523,"props":2688,"children":2689},{"class":525,"line":999},[2690,2695,2699,2704,2708,2712,2716,2720,2724],{"type":41,"tag":523,"props":2691,"children":2692},{"style":1134},[2693],{"type":46,"value":2694},"    const",{"type":41,"tag":523,"props":2696,"children":2697},{"style":552},[2698],{"type":46,"value":1180},{"type":41,"tag":523,"props":2700,"children":2701},{"style":546},[2702],{"type":46,"value":2703}," =",{"type":41,"tag":523,"props":2705,"children":2706},{"style":540},[2707],{"type":46,"value":1348},{"type":41,"tag":523,"props":2709,"children":2710},{"style":613},[2711],{"type":46,"value":2504},{"type":41,"tag":523,"props":2713,"children":2714},{"style":787},[2715],{"type":46,"value":620},{"type":41,"tag":523,"props":2717,"children":2718},{"style":552},[2719],{"type":46,"value":1312},{"type":41,"tag":523,"props":2721,"children":2722},{"style":787},[2723],{"type":46,"value":638},{"type":41,"tag":523,"props":2725,"children":2726},{"style":546},[2727],{"type":46,"value":586},{"type":41,"tag":523,"props":2729,"children":2730},{"class":525,"line":1455},[2731,2736,2740,2745,2749,2754,2759,2764,2769,2773,2777,2782,2786,2790],{"type":41,"tag":523,"props":2732,"children":2733},{"style":540},[2734],{"type":46,"value":2735},"    if",{"type":41,"tag":523,"props":2737,"children":2738},{"style":787},[2739],{"type":46,"value":1306},{"type":41,"tag":523,"props":2741,"children":2742},{"style":546},[2743],{"type":46,"value":2744},"!",{"type":41,"tag":523,"props":2746,"children":2747},{"style":552},[2748],{"type":46,"value":966},{"type":41,"tag":523,"props":2750,"children":2751},{"style":787},[2752],{"type":46,"value":2753},") ",{"type":41,"tag":523,"props":2755,"children":2756},{"style":540},[2757],{"type":46,"value":2758},"throw",{"type":41,"tag":523,"props":2760,"children":2761},{"style":546},[2762],{"type":46,"value":2763}," new",{"type":41,"tag":523,"props":2765,"children":2766},{"style":613},[2767],{"type":46,"value":2768}," Error",{"type":41,"tag":523,"props":2770,"children":2771},{"style":787},[2772],{"type":46,"value":620},{"type":41,"tag":523,"props":2774,"children":2775},{"style":546},[2776],{"type":46,"value":581},{"type":41,"tag":523,"props":2778,"children":2779},{"style":573},[2780],{"type":46,"value":2781},"Not authenticated",{"type":41,"tag":523,"props":2783,"children":2784},{"style":546},[2785],{"type":46,"value":581},{"type":41,"tag":523,"props":2787,"children":2788},{"style":787},[2789],{"type":46,"value":638},{"type":41,"tag":523,"props":2791,"children":2792},{"style":546},[2793],{"type":46,"value":586},{"type":41,"tag":523,"props":2795,"children":2796},{"class":525,"line":1478},[2797],{"type":41,"tag":523,"props":2798,"children":2799},{"emptyLinePlaceholder":593},[2800],{"type":46,"value":596},{"type":41,"tag":523,"props":2802,"children":2803},{"class":525,"line":1495},[2804,2809,2813,2817,2822,2826,2831,2835,2839,2843,2848,2852,2857,2861],{"type":41,"tag":523,"props":2805,"children":2806},{"style":540},[2807],{"type":46,"value":2808},"    await",{"type":41,"tag":523,"props":2810,"children":2811},{"style":552},[2812],{"type":46,"value":1353},{"type":41,"tag":523,"props":2814,"children":2815},{"style":546},[2816],{"type":46,"value":265},{"type":41,"tag":523,"props":2818,"children":2819},{"style":613},[2820],{"type":46,"value":2821},"runMutation",{"type":41,"tag":523,"props":2823,"children":2824},{"style":787},[2825],{"type":46,"value":620},{"type":41,"tag":523,"props":2827,"children":2828},{"style":552},[2829],{"type":46,"value":2830},"components",{"type":41,"tag":523,"props":2832,"children":2833},{"style":546},[2834],{"type":46,"value":265},{"type":41,"tag":523,"props":2836,"children":2837},{"style":552},[2838],{"type":46,"value":629},{"type":41,"tag":523,"props":2840,"children":2841},{"style":546},[2842],{"type":46,"value":265},{"type":41,"tag":523,"props":2844,"children":2845},{"style":552},[2846],{"type":46,"value":2847},"lib",{"type":41,"tag":523,"props":2849,"children":2850},{"style":546},[2851],{"type":46,"value":265},{"type":41,"tag":523,"props":2853,"children":2854},{"style":552},[2855],{"type":46,"value":2856},"send",{"type":41,"tag":523,"props":2858,"children":2859},{"style":546},[2860],{"type":46,"value":678},{"type":41,"tag":523,"props":2862,"children":2863},{"style":546},[2864],{"type":46,"value":1335},{"type":41,"tag":523,"props":2866,"children":2867},{"class":525,"line":1504},[2868,2872],{"type":41,"tag":523,"props":2869,"children":2870},{"style":552},[2871],{"type":46,"value":1403},{"type":41,"tag":523,"props":2873,"children":2874},{"style":546},[2875],{"type":46,"value":842},{"type":41,"tag":523,"props":2877,"children":2878},{"class":525,"line":1520},[2879,2883,2887,2891,2895,2899],{"type":41,"tag":523,"props":2880,"children":2881},{"style":787},[2882],{"type":46,"value":1431},{"type":41,"tag":523,"props":2884,"children":2885},{"style":546},[2886],{"type":46,"value":795},{"type":41,"tag":523,"props":2888,"children":2889},{"style":552},[2890],{"type":46,"value":1321},{"type":41,"tag":523,"props":2892,"children":2893},{"style":546},[2894],{"type":46,"value":265},{"type":41,"tag":523,"props":2896,"children":2897},{"style":552},[2898],{"type":46,"value":1448},{"type":41,"tag":523,"props":2900,"children":2901},{"style":546},[2902],{"type":46,"value":842},{"type":41,"tag":523,"props":2904,"children":2905},{"class":525,"line":1528},[2906,2910,2914],{"type":41,"tag":523,"props":2907,"children":2908},{"style":546},[2909],{"type":46,"value":1484},{"type":41,"tag":523,"props":2911,"children":2912},{"style":787},[2913],{"type":46,"value":638},{"type":41,"tag":523,"props":2915,"children":2916},{"style":546},[2917],{"type":46,"value":586},{"type":41,"tag":523,"props":2919,"children":2920},{"class":525,"line":1561},[2921,2925],{"type":41,"tag":523,"props":2922,"children":2923},{"style":540},[2924],{"type":46,"value":1343},{"type":41,"tag":523,"props":2926,"children":2927},{"style":546},[2928],{"type":46,"value":2929}," null;\n",{"type":41,"tag":523,"props":2931,"children":2932},{"class":525,"line":1605},[2933],{"type":41,"tag":523,"props":2934,"children":2935},{"style":546},[2936],{"type":46,"value":1501},{"type":41,"tag":523,"props":2938,"children":2939},{"class":525,"line":1635},[2940,2944,2948],{"type":41,"tag":523,"props":2941,"children":2942},{"style":546},[2943],{"type":46,"value":1005},{"type":41,"tag":523,"props":2945,"children":2946},{"style":552},[2947],{"type":46,"value":638},{"type":41,"tag":523,"props":2949,"children":2950},{"style":546},[2951],{"type":46,"value":586},{"type":41,"tag":523,"props":2953,"children":2954},{"class":525,"line":1661},[2955],{"type":41,"tag":523,"props":2956,"children":2957},{"emptyLinePlaceholder":593},[2958],{"type":46,"value":596},{"type":41,"tag":523,"props":2960,"children":2961},{"class":525,"line":1710},[2962,2966,2970,2975,2979,2983,2987],{"type":41,"tag":523,"props":2963,"children":2964},{"style":540},[2965],{"type":46,"value":605},{"type":41,"tag":523,"props":2967,"children":2968},{"style":1134},[2969],{"type":46,"value":1137},{"type":41,"tag":523,"props":2971,"children":2972},{"style":552},[2973],{"type":46,"value":2974}," myUnread ",{"type":41,"tag":523,"props":2976,"children":2977},{"style":546},[2978],{"type":46,"value":1147},{"type":41,"tag":523,"props":2980,"children":2981},{"style":613},[2982],{"type":46,"value":1092},{"type":41,"tag":523,"props":2984,"children":2985},{"style":552},[2986],{"type":46,"value":620},{"type":41,"tag":523,"props":2988,"children":2989},{"style":546},[2990],{"type":46,"value":780},{"type":41,"tag":523,"props":2992,"children":2993},{"class":525,"line":1744},[2994,2998,3002],{"type":41,"tag":523,"props":2995,"children":2996},{"style":787},[2997],{"type":46,"value":1167},{"type":41,"tag":523,"props":2999,"children":3000},{"style":546},[3001],{"type":46,"value":795},{"type":41,"tag":523,"props":3003,"children":3004},{"style":546},[3005],{"type":46,"value":3006}," {},\n",{"type":41,"tag":523,"props":3008,"children":3009},{"class":525,"line":1776},[3010,3014,3018,3022,3026,3030,3034,3038],{"type":41,"tag":523,"props":3011,"children":3012},{"style":613},[3013],{"type":46,"value":1292},{"type":41,"tag":523,"props":3015,"children":3016},{"style":546},[3017],{"type":46,"value":795},{"type":41,"tag":523,"props":3019,"children":3020},{"style":1134},[3021],{"type":46,"value":1301},{"type":41,"tag":523,"props":3023,"children":3024},{"style":546},[3025],{"type":46,"value":1306},{"type":41,"tag":523,"props":3027,"children":3028},{"style":1309},[3029],{"type":46,"value":1312},{"type":41,"tag":523,"props":3031,"children":3032},{"style":546},[3033],{"type":46,"value":638},{"type":41,"tag":523,"props":3035,"children":3036},{"style":1134},[3037],{"type":46,"value":1330},{"type":41,"tag":523,"props":3039,"children":3040},{"style":546},[3041],{"type":46,"value":1335},{"type":41,"tag":523,"props":3043,"children":3044},{"class":525,"line":1808},[3045,3049,3053,3057,3061,3065,3069,3073,3077],{"type":41,"tag":523,"props":3046,"children":3047},{"style":1134},[3048],{"type":46,"value":2694},{"type":41,"tag":523,"props":3050,"children":3051},{"style":552},[3052],{"type":46,"value":1180},{"type":41,"tag":523,"props":3054,"children":3055},{"style":546},[3056],{"type":46,"value":2703},{"type":41,"tag":523,"props":3058,"children":3059},{"style":540},[3060],{"type":46,"value":1348},{"type":41,"tag":523,"props":3062,"children":3063},{"style":613},[3064],{"type":46,"value":2504},{"type":41,"tag":523,"props":3066,"children":3067},{"style":787},[3068],{"type":46,"value":620},{"type":41,"tag":523,"props":3070,"children":3071},{"style":552},[3072],{"type":46,"value":1312},{"type":41,"tag":523,"props":3074,"children":3075},{"style":787},[3076],{"type":46,"value":638},{"type":41,"tag":523,"props":3078,"children":3079},{"style":546},[3080],{"type":46,"value":586},{"type":41,"tag":523,"props":3082,"children":3083},{"class":525,"line":1840},[3084,3088,3092,3096,3100,3104,3108,3112,3116,3120,3124,3128,3132,3136],{"type":41,"tag":523,"props":3085,"children":3086},{"style":540},[3087],{"type":46,"value":2735},{"type":41,"tag":523,"props":3089,"children":3090},{"style":787},[3091],{"type":46,"value":1306},{"type":41,"tag":523,"props":3093,"children":3094},{"style":546},[3095],{"type":46,"value":2744},{"type":41,"tag":523,"props":3097,"children":3098},{"style":552},[3099],{"type":46,"value":966},{"type":41,"tag":523,"props":3101,"children":3102},{"style":787},[3103],{"type":46,"value":2753},{"type":41,"tag":523,"props":3105,"children":3106},{"style":540},[3107],{"type":46,"value":2758},{"type":41,"tag":523,"props":3109,"children":3110},{"style":546},[3111],{"type":46,"value":2763},{"type":41,"tag":523,"props":3113,"children":3114},{"style":613},[3115],{"type":46,"value":2768},{"type":41,"tag":523,"props":3117,"children":3118},{"style":787},[3119],{"type":46,"value":620},{"type":41,"tag":523,"props":3121,"children":3122},{"style":546},[3123],{"type":46,"value":581},{"type":41,"tag":523,"props":3125,"children":3126},{"style":573},[3127],{"type":46,"value":2781},{"type":41,"tag":523,"props":3129,"children":3130},{"style":546},[3131],{"type":46,"value":581},{"type":41,"tag":523,"props":3133,"children":3134},{"style":787},[3135],{"type":46,"value":638},{"type":41,"tag":523,"props":3137,"children":3138},{"style":546},[3139],{"type":46,"value":586},{"type":41,"tag":523,"props":3141,"children":3142},{"class":525,"line":1856},[3143],{"type":41,"tag":523,"props":3144,"children":3145},{"emptyLinePlaceholder":593},[3146],{"type":46,"value":596},{"type":41,"tag":523,"props":3148,"children":3149},{"class":525,"line":1869},[3150,3154,3158,3162,3166,3171,3175,3179,3183,3187,3191,3195,3199,3204,3208],{"type":41,"tag":523,"props":3151,"children":3152},{"style":540},[3153],{"type":46,"value":1343},{"type":41,"tag":523,"props":3155,"children":3156},{"style":540},[3157],{"type":46,"value":1348},{"type":41,"tag":523,"props":3159,"children":3160},{"style":552},[3161],{"type":46,"value":1353},{"type":41,"tag":523,"props":3163,"children":3164},{"style":546},[3165],{"type":46,"value":265},{"type":41,"tag":523,"props":3167,"children":3168},{"style":613},[3169],{"type":46,"value":3170},"runQuery",{"type":41,"tag":523,"props":3172,"children":3173},{"style":787},[3174],{"type":46,"value":620},{"type":41,"tag":523,"props":3176,"children":3177},{"style":552},[3178],{"type":46,"value":2830},{"type":41,"tag":523,"props":3180,"children":3181},{"style":546},[3182],{"type":46,"value":265},{"type":41,"tag":523,"props":3184,"children":3185},{"style":552},[3186],{"type":46,"value":629},{"type":41,"tag":523,"props":3188,"children":3189},{"style":546},[3190],{"type":46,"value":265},{"type":41,"tag":523,"props":3192,"children":3193},{"style":552},[3194],{"type":46,"value":2847},{"type":41,"tag":523,"props":3196,"children":3197},{"style":546},[3198],{"type":46,"value":265},{"type":41,"tag":523,"props":3200,"children":3201},{"style":552},[3202],{"type":46,"value":3203},"listUnread",{"type":41,"tag":523,"props":3205,"children":3206},{"style":546},[3207],{"type":46,"value":678},{"type":41,"tag":523,"props":3209,"children":3210},{"style":546},[3211],{"type":46,"value":1335},{"type":41,"tag":523,"props":3213,"children":3214},{"class":525,"line":1913},[3215,3219],{"type":41,"tag":523,"props":3216,"children":3217},{"style":552},[3218],{"type":46,"value":1403},{"type":41,"tag":523,"props":3220,"children":3221},{"style":546},[3222],{"type":46,"value":842},{"type":41,"tag":523,"props":3224,"children":3225},{"class":525,"line":1938},[3226,3230,3234],{"type":41,"tag":523,"props":3227,"children":3228},{"style":546},[3229],{"type":46,"value":1484},{"type":41,"tag":523,"props":3231,"children":3232},{"style":787},[3233],{"type":46,"value":638},{"type":41,"tag":523,"props":3235,"children":3236},{"style":546},[3237],{"type":46,"value":586},{"type":41,"tag":523,"props":3239,"children":3240},{"class":525,"line":1973},[3241],{"type":41,"tag":523,"props":3242,"children":3243},{"style":546},[3244],{"type":46,"value":1501},{"type":41,"tag":523,"props":3246,"children":3247},{"class":525,"line":2024},[3248,3252,3256],{"type":41,"tag":523,"props":3249,"children":3250},{"style":546},[3251],{"type":46,"value":1005},{"type":41,"tag":523,"props":3253,"children":3254},{"style":552},[3255],{"type":46,"value":638},{"type":41,"tag":523,"props":3257,"children":3258},{"style":546},[3259],{"type":46,"value":586},{"type":41,"tag":49,"props":3261,"children":3262},{},[3263,3265,3271,3273,3279],{"type":46,"value":3264},"Note the reference path shape: a function in\n",{"type":41,"tag":111,"props":3266,"children":3268},{"className":3267},[],[3269],{"type":46,"value":3270},"convex\u002Fcomponents\u002Fnotifications\u002Flib.ts",{"type":46,"value":3272}," is called as\n",{"type":41,"tag":111,"props":3274,"children":3276},{"className":3275},[],[3277],{"type":46,"value":3278},"components.notifications.lib.send",{"type":46,"value":3280}," from the app.",{"type":41,"tag":55,"props":3282,"children":3284},{"id":3283},"critical-rules",[3285],{"type":46,"value":3286},"Critical Rules",{"type":41,"tag":62,"props":3288,"children":3289},{},[3290,3303,3315,3335,3348,3382,3387,3400,3436,3449],{"type":41,"tag":66,"props":3291,"children":3292},{},[3293,3295,3301],{"type":46,"value":3294},"Keep authentication in the app, because ",{"type":41,"tag":111,"props":3296,"children":3298},{"className":3297},[],[3299],{"type":46,"value":3300},"ctx.auth",{"type":46,"value":3302}," is not available inside\ncomponents.",{"type":41,"tag":66,"props":3304,"children":3305},{},[3306,3308,3314],{"type":46,"value":3307},"Keep environment access in the app, because component functions cannot read\n",{"type":41,"tag":111,"props":3309,"children":3311},{"className":3310},[],[3312],{"type":46,"value":3313},"process.env",{"type":46,"value":265},{"type":41,"tag":66,"props":3316,"children":3317},{},[3318,3320,3326,3328,3334],{"type":46,"value":3319},"Pass parent app IDs across the boundary as strings, because ",{"type":41,"tag":111,"props":3321,"children":3323},{"className":3322},[],[3324],{"type":46,"value":3325},"Id",{"type":46,"value":3327}," types become\nplain strings in the app-facing ",{"type":41,"tag":111,"props":3329,"children":3331},{"className":3330},[],[3332],{"type":46,"value":3333},"ComponentApi",{"type":46,"value":265},{"type":41,"tag":66,"props":3336,"children":3337},{},[3338,3340,3346],{"type":46,"value":3339},"Do not use ",{"type":41,"tag":111,"props":3341,"children":3343},{"className":3342},[],[3344],{"type":46,"value":3345},"v.id(\"parentTable\")",{"type":46,"value":3347}," for app-owned tables inside component args or\nschema, because the component has no access to the app's table namespace.",{"type":41,"tag":66,"props":3349,"children":3350},{},[3351,3353,3358,3359,3365,3367,3373,3375,3380],{"type":46,"value":3352},"Import ",{"type":41,"tag":111,"props":3354,"children":3356},{"className":3355},[],[3357],{"type":46,"value":1949},{"type":46,"value":187},{"type":41,"tag":111,"props":3360,"children":3362},{"className":3361},[],[3363],{"type":46,"value":3364},"mutation",{"type":46,"value":3366},", and ",{"type":41,"tag":111,"props":3368,"children":3370},{"className":3369},[],[3371],{"type":46,"value":3372},"action",{"type":46,"value":3374}," from the component's own\n",{"type":41,"tag":111,"props":3376,"children":3378},{"className":3377},[],[3379],{"type":46,"value":206},{"type":46,"value":3381},", not the app's generated files.",{"type":41,"tag":66,"props":3383,"children":3384},{},[3385],{"type":46,"value":3386},"Do not expose component functions directly to clients. Create app wrappers\nwhen client access is needed, because components are internal and need\nauth\u002Fenv wiring the app provides.",{"type":41,"tag":66,"props":3388,"children":3389},{},[3390,3392,3398],{"type":46,"value":3391},"If the component defines HTTP handlers, mount the routes in the app's\n",{"type":41,"tag":111,"props":3393,"children":3395},{"className":3394},[],[3396],{"type":46,"value":3397},"convex\u002Fhttp.ts",{"type":46,"value":3399},", because components cannot register their own HTTP routes.",{"type":41,"tag":66,"props":3401,"children":3402},{},[3403,3405,3411,3413,3419,3421,3427,3429,3434],{"type":46,"value":3404},"If the component needs pagination, use ",{"type":41,"tag":111,"props":3406,"children":3408},{"className":3407},[],[3409],{"type":46,"value":3410},"paginator",{"type":46,"value":3412}," from ",{"type":41,"tag":111,"props":3414,"children":3416},{"className":3415},[],[3417],{"type":46,"value":3418},"convex-helpers",{"type":46,"value":3420},"\ninstead of built-in ",{"type":41,"tag":111,"props":3422,"children":3424},{"className":3423},[],[3425],{"type":46,"value":3426},".paginate()",{"type":46,"value":3428},", because ",{"type":41,"tag":111,"props":3430,"children":3432},{"className":3431},[],[3433],{"type":46,"value":3426},{"type":46,"value":3435}," does not work across\nthe component boundary.",{"type":41,"tag":66,"props":3437,"children":3438},{},[3439,3441,3447],{"type":46,"value":3440},"Define indexes for queried fields instead of using Convex ",{"type":41,"tag":111,"props":3442,"children":3444},{"className":3443},[],[3445],{"type":46,"value":3446},".filter()",{"type":46,"value":3448}," after a\ndatabase query.",{"type":41,"tag":66,"props":3450,"children":3451},{},[3452,3454,3460,3462,3468],{"type":46,"value":3453},"Add ",{"type":41,"tag":111,"props":3455,"children":3457},{"className":3456},[],[3458],{"type":46,"value":3459},"args",{"type":46,"value":3461}," and ",{"type":41,"tag":111,"props":3463,"children":3465},{"className":3464},[],[3466],{"type":46,"value":3467},"returns",{"type":46,"value":3469}," validators to all public component functions, because\nthe component boundary requires explicit type contracts.",{"type":41,"tag":55,"props":3471,"children":3473},{"id":3472},"patterns",[3474],{"type":46,"value":3475},"Patterns",{"type":41,"tag":3477,"props":3478,"children":3480},"h3",{"id":3479},"authentication-and-environment-access",[3481],{"type":46,"value":3482},"Authentication and environment access",{"type":41,"tag":512,"props":3484,"children":3486},{"className":514,"code":3485,"language":516,"meta":517,"style":517},"\u002F\u002F Bad: component code cannot rely on app auth or env\nconst identity = await ctx.auth.getUserIdentity();\nconst apiKey = process.env.OPENAI_API_KEY;\n",[3487],{"type":41,"tag":111,"props":3488,"children":3489},{"__ignoreMap":517},[3490,3498,3548],{"type":41,"tag":523,"props":3491,"children":3492},{"class":525,"line":526},[3493],{"type":41,"tag":523,"props":3494,"children":3495},{"style":530},[3496],{"type":46,"value":3497},"\u002F\u002F Bad: component code cannot rely on app auth or env\n",{"type":41,"tag":523,"props":3499,"children":3500},{"class":525,"line":536},[3501,3505,3510,3514,3518,3522,3526,3531,3535,3540,3544],{"type":41,"tag":523,"props":3502,"children":3503},{"style":1134},[3504],{"type":46,"value":2272},{"type":41,"tag":523,"props":3506,"children":3507},{"style":552},[3508],{"type":46,"value":3509}," identity ",{"type":41,"tag":523,"props":3511,"children":3512},{"style":546},[3513],{"type":46,"value":1147},{"type":41,"tag":523,"props":3515,"children":3516},{"style":540},[3517],{"type":46,"value":1348},{"type":41,"tag":523,"props":3519,"children":3520},{"style":552},[3521],{"type":46,"value":1353},{"type":41,"tag":523,"props":3523,"children":3524},{"style":546},[3525],{"type":46,"value":265},{"type":41,"tag":523,"props":3527,"children":3528},{"style":552},[3529],{"type":46,"value":3530},"auth",{"type":41,"tag":523,"props":3532,"children":3533},{"style":546},[3534],{"type":46,"value":265},{"type":41,"tag":523,"props":3536,"children":3537},{"style":613},[3538],{"type":46,"value":3539},"getUserIdentity",{"type":41,"tag":523,"props":3541,"children":3542},{"style":552},[3543],{"type":46,"value":837},{"type":41,"tag":523,"props":3545,"children":3546},{"style":546},[3547],{"type":46,"value":586},{"type":41,"tag":523,"props":3549,"children":3550},{"class":525,"line":589},[3551,3555,3560,3564,3569,3573,3578,3582,3587],{"type":41,"tag":523,"props":3552,"children":3553},{"style":1134},[3554],{"type":46,"value":2272},{"type":41,"tag":523,"props":3556,"children":3557},{"style":552},[3558],{"type":46,"value":3559}," apiKey ",{"type":41,"tag":523,"props":3561,"children":3562},{"style":546},[3563],{"type":46,"value":1147},{"type":41,"tag":523,"props":3565,"children":3566},{"style":552},[3567],{"type":46,"value":3568}," process",{"type":41,"tag":523,"props":3570,"children":3571},{"style":546},[3572],{"type":46,"value":265},{"type":41,"tag":523,"props":3574,"children":3575},{"style":552},[3576],{"type":46,"value":3577},"env",{"type":41,"tag":523,"props":3579,"children":3580},{"style":546},[3581],{"type":46,"value":265},{"type":41,"tag":523,"props":3583,"children":3584},{"style":552},[3585],{"type":46,"value":3586},"OPENAI_API_KEY",{"type":41,"tag":523,"props":3588,"children":3589},{"style":546},[3590],{"type":46,"value":586},{"type":41,"tag":512,"props":3592,"children":3594},{"className":514,"code":3593,"language":516,"meta":517,"style":517},"\u002F\u002F Good: the app resolves auth and env, then passes explicit values\nconst userId = await getAuthUserId(ctx);\nif (!userId) throw new Error(\"Not authenticated\");\n\nawait ctx.runAction(components.translator.translate, {\n  userId,\n  apiKey: process.env.OPENAI_API_KEY,\n  text: args.text,\n});\n",[3595],{"type":41,"tag":111,"props":3596,"children":3597},{"__ignoreMap":517},[3598,3606,3639,3696,3703,3755,3767,3803,3831],{"type":41,"tag":523,"props":3599,"children":3600},{"class":525,"line":526},[3601],{"type":41,"tag":523,"props":3602,"children":3603},{"style":530},[3604],{"type":46,"value":3605},"\u002F\u002F Good: the app resolves auth and env, then passes explicit values\n",{"type":41,"tag":523,"props":3607,"children":3608},{"class":525,"line":536},[3609,3613,3618,3622,3626,3630,3635],{"type":41,"tag":523,"props":3610,"children":3611},{"style":1134},[3612],{"type":46,"value":2272},{"type":41,"tag":523,"props":3614,"children":3615},{"style":552},[3616],{"type":46,"value":3617}," userId ",{"type":41,"tag":523,"props":3619,"children":3620},{"style":546},[3621],{"type":46,"value":1147},{"type":41,"tag":523,"props":3623,"children":3624},{"style":540},[3625],{"type":46,"value":1348},{"type":41,"tag":523,"props":3627,"children":3628},{"style":613},[3629],{"type":46,"value":2504},{"type":41,"tag":523,"props":3631,"children":3632},{"style":552},[3633],{"type":46,"value":3634},"(ctx)",{"type":41,"tag":523,"props":3636,"children":3637},{"style":546},[3638],{"type":46,"value":586},{"type":41,"tag":523,"props":3640,"children":3641},{"class":525,"line":589},[3642,3647,3651,3655,3660,3664,3668,3672,3676,3680,3684,3688,3692],{"type":41,"tag":523,"props":3643,"children":3644},{"style":540},[3645],{"type":46,"value":3646},"if",{"type":41,"tag":523,"props":3648,"children":3649},{"style":552},[3650],{"type":46,"value":1306},{"type":41,"tag":523,"props":3652,"children":3653},{"style":546},[3654],{"type":46,"value":2744},{"type":41,"tag":523,"props":3656,"children":3657},{"style":552},[3658],{"type":46,"value":3659},"userId) ",{"type":41,"tag":523,"props":3661,"children":3662},{"style":540},[3663],{"type":46,"value":2758},{"type":41,"tag":523,"props":3665,"children":3666},{"style":546},[3667],{"type":46,"value":2763},{"type":41,"tag":523,"props":3669,"children":3670},{"style":613},[3671],{"type":46,"value":2768},{"type":41,"tag":523,"props":3673,"children":3674},{"style":552},[3675],{"type":46,"value":620},{"type":41,"tag":523,"props":3677,"children":3678},{"style":546},[3679],{"type":46,"value":581},{"type":41,"tag":523,"props":3681,"children":3682},{"style":573},[3683],{"type":46,"value":2781},{"type":41,"tag":523,"props":3685,"children":3686},{"style":546},[3687],{"type":46,"value":581},{"type":41,"tag":523,"props":3689,"children":3690},{"style":552},[3691],{"type":46,"value":638},{"type":41,"tag":523,"props":3693,"children":3694},{"style":546},[3695],{"type":46,"value":586},{"type":41,"tag":523,"props":3697,"children":3698},{"class":525,"line":599},[3699],{"type":41,"tag":523,"props":3700,"children":3701},{"emptyLinePlaceholder":593},[3702],{"type":46,"value":596},{"type":41,"tag":523,"props":3704,"children":3705},{"class":525,"line":758},[3706,3711,3715,3719,3724,3729,3733,3738,3742,3747,3751],{"type":41,"tag":523,"props":3707,"children":3708},{"style":540},[3709],{"type":46,"value":3710},"await",{"type":41,"tag":523,"props":3712,"children":3713},{"style":552},[3714],{"type":46,"value":1353},{"type":41,"tag":523,"props":3716,"children":3717},{"style":546},[3718],{"type":46,"value":265},{"type":41,"tag":523,"props":3720,"children":3721},{"style":613},[3722],{"type":46,"value":3723},"runAction",{"type":41,"tag":523,"props":3725,"children":3726},{"style":552},[3727],{"type":46,"value":3728},"(components",{"type":41,"tag":523,"props":3730,"children":3731},{"style":546},[3732],{"type":46,"value":265},{"type":41,"tag":523,"props":3734,"children":3735},{"style":552},[3736],{"type":46,"value":3737},"translator",{"type":41,"tag":523,"props":3739,"children":3740},{"style":546},[3741],{"type":46,"value":265},{"type":41,"tag":523,"props":3743,"children":3744},{"style":552},[3745],{"type":46,"value":3746},"translate",{"type":41,"tag":523,"props":3748,"children":3749},{"style":546},[3750],{"type":46,"value":678},{"type":41,"tag":523,"props":3752,"children":3753},{"style":546},[3754],{"type":46,"value":1335},{"type":41,"tag":523,"props":3756,"children":3757},{"class":525,"line":783},[3758,3763],{"type":41,"tag":523,"props":3759,"children":3760},{"style":552},[3761],{"type":46,"value":3762},"  userId",{"type":41,"tag":523,"props":3764,"children":3765},{"style":546},[3766],{"type":46,"value":842},{"type":41,"tag":523,"props":3768,"children":3769},{"class":525,"line":28},[3770,3775,3779,3783,3787,3791,3795,3799],{"type":41,"tag":523,"props":3771,"children":3772},{"style":787},[3773],{"type":46,"value":3774},"  apiKey",{"type":41,"tag":523,"props":3776,"children":3777},{"style":546},[3778],{"type":46,"value":795},{"type":41,"tag":523,"props":3780,"children":3781},{"style":552},[3782],{"type":46,"value":3568},{"type":41,"tag":523,"props":3784,"children":3785},{"style":546},[3786],{"type":46,"value":265},{"type":41,"tag":523,"props":3788,"children":3789},{"style":552},[3790],{"type":46,"value":3577},{"type":41,"tag":523,"props":3792,"children":3793},{"style":546},[3794],{"type":46,"value":265},{"type":41,"tag":523,"props":3796,"children":3797},{"style":552},[3798],{"type":46,"value":3586},{"type":41,"tag":523,"props":3800,"children":3801},{"style":546},[3802],{"type":46,"value":842},{"type":41,"tag":523,"props":3804,"children":3805},{"class":525,"line":845},[3806,3811,3815,3819,3823,3827],{"type":41,"tag":523,"props":3807,"children":3808},{"style":787},[3809],{"type":46,"value":3810},"  text",{"type":41,"tag":523,"props":3812,"children":3813},{"style":546},[3814],{"type":46,"value":795},{"type":41,"tag":523,"props":3816,"children":3817},{"style":552},[3818],{"type":46,"value":1321},{"type":41,"tag":523,"props":3820,"children":3821},{"style":546},[3822],{"type":46,"value":265},{"type":41,"tag":523,"props":3824,"children":3825},{"style":552},[3826],{"type":46,"value":46},{"type":41,"tag":523,"props":3828,"children":3829},{"style":546},[3830],{"type":46,"value":842},{"type":41,"tag":523,"props":3832,"children":3833},{"class":525,"line":878},[3834,3838,3842],{"type":41,"tag":523,"props":3835,"children":3836},{"style":546},[3837],{"type":46,"value":1005},{"type":41,"tag":523,"props":3839,"children":3840},{"style":552},[3841],{"type":46,"value":638},{"type":41,"tag":523,"props":3843,"children":3844},{"style":546},[3845],{"type":46,"value":586},{"type":41,"tag":3477,"props":3847,"children":3849},{"id":3848},"client-facing-api",[3850],{"type":46,"value":3851},"Client-facing API",{"type":41,"tag":512,"props":3853,"children":3855},{"className":514,"code":3854,"language":516,"meta":517,"style":517},"\u002F\u002F Bad: assuming a component function is directly callable by clients\nexport const send = components.notifications.send;\n",[3856],{"type":41,"tag":111,"props":3857,"children":3858},{"__ignoreMap":517},[3859,3867],{"type":41,"tag":523,"props":3860,"children":3861},{"class":525,"line":526},[3862],{"type":41,"tag":523,"props":3863,"children":3864},{"style":530},[3865],{"type":46,"value":3866},"\u002F\u002F Bad: assuming a component function is directly callable by clients\n",{"type":41,"tag":523,"props":3868,"children":3869},{"class":525,"line":536},[3870,3874,3878,3882,3886,3890,3894,3898,3902,3906],{"type":41,"tag":523,"props":3871,"children":3872},{"style":540},[3873],{"type":46,"value":605},{"type":41,"tag":523,"props":3875,"children":3876},{"style":1134},[3877],{"type":46,"value":1137},{"type":41,"tag":523,"props":3879,"children":3880},{"style":552},[3881],{"type":46,"value":1142},{"type":41,"tag":523,"props":3883,"children":3884},{"style":546},[3885],{"type":46,"value":1147},{"type":41,"tag":523,"props":3887,"children":3888},{"style":552},[3889],{"type":46,"value":2463},{"type":41,"tag":523,"props":3891,"children":3892},{"style":546},[3893],{"type":46,"value":265},{"type":41,"tag":523,"props":3895,"children":3896},{"style":552},[3897],{"type":46,"value":629},{"type":41,"tag":523,"props":3899,"children":3900},{"style":546},[3901],{"type":46,"value":265},{"type":41,"tag":523,"props":3903,"children":3904},{"style":552},[3905],{"type":46,"value":2856},{"type":41,"tag":523,"props":3907,"children":3908},{"style":546},[3909],{"type":46,"value":586},{"type":41,"tag":512,"props":3911,"children":3913},{"className":514,"code":3912,"language":516,"meta":517,"style":517},"\u002F\u002F Good: re-export through an app mutation or query\nexport const sendNotification = mutation({\n  args: { message: v.string() },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    const userId = await getAuthUserId(ctx);\n    if (!userId) throw new Error(\"Not authenticated\");\n\n    await ctx.runMutation(components.notifications.lib.send, {\n      userId,\n      message: args.message,\n    });\n    return null;\n  },\n});\n",[3914],{"type":41,"tag":111,"props":3915,"children":3916},{"__ignoreMap":517},[3917,3925,3956,3999,4030,4073,4112,4171,4178,4237,4248,4275,4290,4301,4308],{"type":41,"tag":523,"props":3918,"children":3919},{"class":525,"line":526},[3920],{"type":41,"tag":523,"props":3921,"children":3922},{"style":530},[3923],{"type":46,"value":3924},"\u002F\u002F Good: re-export through an app mutation or query\n",{"type":41,"tag":523,"props":3926,"children":3927},{"class":525,"line":536},[3928,3932,3936,3940,3944,3948,3952],{"type":41,"tag":523,"props":3929,"children":3930},{"style":540},[3931],{"type":46,"value":605},{"type":41,"tag":523,"props":3933,"children":3934},{"style":1134},[3935],{"type":46,"value":1137},{"type":41,"tag":523,"props":3937,"children":3938},{"style":552},[3939],{"type":46,"value":2552},{"type":41,"tag":523,"props":3941,"children":3942},{"style":546},[3943],{"type":46,"value":1147},{"type":41,"tag":523,"props":3945,"children":3946},{"style":613},[3947],{"type":46,"value":1083},{"type":41,"tag":523,"props":3949,"children":3950},{"style":552},[3951],{"type":46,"value":620},{"type":41,"tag":523,"props":3953,"children":3954},{"style":546},[3955],{"type":46,"value":780},{"type":41,"tag":523,"props":3957,"children":3958},{"class":525,"line":589},[3959,3963,3967,3971,3975,3979,3983,3987,3991,3995],{"type":41,"tag":523,"props":3960,"children":3961},{"style":787},[3962],{"type":46,"value":1167},{"type":41,"tag":523,"props":3964,"children":3965},{"style":546},[3966],{"type":46,"value":795},{"type":41,"tag":523,"props":3968,"children":3969},{"style":546},[3970],{"type":46,"value":549},{"type":41,"tag":523,"props":3972,"children":3973},{"style":787},[3974],{"type":46,"value":1209},{"type":41,"tag":523,"props":3976,"children":3977},{"style":546},[3978],{"type":46,"value":795},{"type":41,"tag":523,"props":3980,"children":3981},{"style":552},[3982],{"type":46,"value":723},{"type":41,"tag":523,"props":3984,"children":3985},{"style":546},[3986],{"type":46,"value":265},{"type":41,"tag":523,"props":3988,"children":3989},{"style":613},[3990],{"type":46,"value":832},{"type":41,"tag":523,"props":3992,"children":3993},{"style":552},[3994],{"type":46,"value":1230},{"type":41,"tag":523,"props":3996,"children":3997},{"style":546},[3998],{"type":46,"value":1235},{"type":41,"tag":523,"props":4000,"children":4001},{"class":525,"line":599},[4002,4006,4010,4014,4018,4022,4026],{"type":41,"tag":523,"props":4003,"children":4004},{"style":787},[4005],{"type":46,"value":1243},{"type":41,"tag":523,"props":4007,"children":4008},{"style":546},[4009],{"type":46,"value":795},{"type":41,"tag":523,"props":4011,"children":4012},{"style":552},[4013],{"type":46,"value":723},{"type":41,"tag":523,"props":4015,"children":4016},{"style":546},[4017],{"type":46,"value":265},{"type":41,"tag":523,"props":4019,"children":4020},{"style":613},[4021],{"type":46,"value":2635},{"type":41,"tag":523,"props":4023,"children":4024},{"style":552},[4025],{"type":46,"value":837},{"type":41,"tag":523,"props":4027,"children":4028},{"style":546},[4029],{"type":46,"value":842},{"type":41,"tag":523,"props":4031,"children":4032},{"class":525,"line":758},[4033,4037,4041,4045,4049,4053,4057,4061,4065,4069],{"type":41,"tag":523,"props":4034,"children":4035},{"style":613},[4036],{"type":46,"value":1292},{"type":41,"tag":523,"props":4038,"children":4039},{"style":546},[4040],{"type":46,"value":795},{"type":41,"tag":523,"props":4042,"children":4043},{"style":1134},[4044],{"type":46,"value":1301},{"type":41,"tag":523,"props":4046,"children":4047},{"style":546},[4048],{"type":46,"value":1306},{"type":41,"tag":523,"props":4050,"children":4051},{"style":1309},[4052],{"type":46,"value":1312},{"type":41,"tag":523,"props":4054,"children":4055},{"style":546},[4056],{"type":46,"value":678},{"type":41,"tag":523,"props":4058,"children":4059},{"style":1309},[4060],{"type":46,"value":1321},{"type":41,"tag":523,"props":4062,"children":4063},{"style":546},[4064],{"type":46,"value":638},{"type":41,"tag":523,"props":4066,"children":4067},{"style":1134},[4068],{"type":46,"value":1330},{"type":41,"tag":523,"props":4070,"children":4071},{"style":546},[4072],{"type":46,"value":1335},{"type":41,"tag":523,"props":4074,"children":4075},{"class":525,"line":783},[4076,4080,4084,4088,4092,4096,4100,4104,4108],{"type":41,"tag":523,"props":4077,"children":4078},{"style":1134},[4079],{"type":46,"value":2694},{"type":41,"tag":523,"props":4081,"children":4082},{"style":552},[4083],{"type":46,"value":1180},{"type":41,"tag":523,"props":4085,"children":4086},{"style":546},[4087],{"type":46,"value":2703},{"type":41,"tag":523,"props":4089,"children":4090},{"style":540},[4091],{"type":46,"value":1348},{"type":41,"tag":523,"props":4093,"children":4094},{"style":613},[4095],{"type":46,"value":2504},{"type":41,"tag":523,"props":4097,"children":4098},{"style":787},[4099],{"type":46,"value":620},{"type":41,"tag":523,"props":4101,"children":4102},{"style":552},[4103],{"type":46,"value":1312},{"type":41,"tag":523,"props":4105,"children":4106},{"style":787},[4107],{"type":46,"value":638},{"type":41,"tag":523,"props":4109,"children":4110},{"style":546},[4111],{"type":46,"value":586},{"type":41,"tag":523,"props":4113,"children":4114},{"class":525,"line":28},[4115,4119,4123,4127,4131,4135,4139,4143,4147,4151,4155,4159,4163,4167],{"type":41,"tag":523,"props":4116,"children":4117},{"style":540},[4118],{"type":46,"value":2735},{"type":41,"tag":523,"props":4120,"children":4121},{"style":787},[4122],{"type":46,"value":1306},{"type":41,"tag":523,"props":4124,"children":4125},{"style":546},[4126],{"type":46,"value":2744},{"type":41,"tag":523,"props":4128,"children":4129},{"style":552},[4130],{"type":46,"value":966},{"type":41,"tag":523,"props":4132,"children":4133},{"style":787},[4134],{"type":46,"value":2753},{"type":41,"tag":523,"props":4136,"children":4137},{"style":540},[4138],{"type":46,"value":2758},{"type":41,"tag":523,"props":4140,"children":4141},{"style":546},[4142],{"type":46,"value":2763},{"type":41,"tag":523,"props":4144,"children":4145},{"style":613},[4146],{"type":46,"value":2768},{"type":41,"tag":523,"props":4148,"children":4149},{"style":787},[4150],{"type":46,"value":620},{"type":41,"tag":523,"props":4152,"children":4153},{"style":546},[4154],{"type":46,"value":581},{"type":41,"tag":523,"props":4156,"children":4157},{"style":573},[4158],{"type":46,"value":2781},{"type":41,"tag":523,"props":4160,"children":4161},{"style":546},[4162],{"type":46,"value":581},{"type":41,"tag":523,"props":4164,"children":4165},{"style":787},[4166],{"type":46,"value":638},{"type":41,"tag":523,"props":4168,"children":4169},{"style":546},[4170],{"type":46,"value":586},{"type":41,"tag":523,"props":4172,"children":4173},{"class":525,"line":845},[4174],{"type":41,"tag":523,"props":4175,"children":4176},{"emptyLinePlaceholder":593},[4177],{"type":46,"value":596},{"type":41,"tag":523,"props":4179,"children":4180},{"class":525,"line":878},[4181,4185,4189,4193,4197,4201,4205,4209,4213,4217,4221,4225,4229,4233],{"type":41,"tag":523,"props":4182,"children":4183},{"style":540},[4184],{"type":46,"value":2808},{"type":41,"tag":523,"props":4186,"children":4187},{"style":552},[4188],{"type":46,"value":1353},{"type":41,"tag":523,"props":4190,"children":4191},{"style":546},[4192],{"type":46,"value":265},{"type":41,"tag":523,"props":4194,"children":4195},{"style":613},[4196],{"type":46,"value":2821},{"type":41,"tag":523,"props":4198,"children":4199},{"style":787},[4200],{"type":46,"value":620},{"type":41,"tag":523,"props":4202,"children":4203},{"style":552},[4204],{"type":46,"value":2830},{"type":41,"tag":523,"props":4206,"children":4207},{"style":546},[4208],{"type":46,"value":265},{"type":41,"tag":523,"props":4210,"children":4211},{"style":552},[4212],{"type":46,"value":629},{"type":41,"tag":523,"props":4214,"children":4215},{"style":546},[4216],{"type":46,"value":265},{"type":41,"tag":523,"props":4218,"children":4219},{"style":552},[4220],{"type":46,"value":2847},{"type":41,"tag":523,"props":4222,"children":4223},{"style":546},[4224],{"type":46,"value":265},{"type":41,"tag":523,"props":4226,"children":4227},{"style":552},[4228],{"type":46,"value":2856},{"type":41,"tag":523,"props":4230,"children":4231},{"style":546},[4232],{"type":46,"value":678},{"type":41,"tag":523,"props":4234,"children":4235},{"style":546},[4236],{"type":46,"value":1335},{"type":41,"tag":523,"props":4238,"children":4239},{"class":525,"line":912},[4240,4244],{"type":41,"tag":523,"props":4241,"children":4242},{"style":552},[4243],{"type":46,"value":1403},{"type":41,"tag":523,"props":4245,"children":4246},{"style":546},[4247],{"type":46,"value":842},{"type":41,"tag":523,"props":4249,"children":4250},{"class":525,"line":999},[4251,4255,4259,4263,4267,4271],{"type":41,"tag":523,"props":4252,"children":4253},{"style":787},[4254],{"type":46,"value":1431},{"type":41,"tag":523,"props":4256,"children":4257},{"style":546},[4258],{"type":46,"value":795},{"type":41,"tag":523,"props":4260,"children":4261},{"style":552},[4262],{"type":46,"value":1321},{"type":41,"tag":523,"props":4264,"children":4265},{"style":546},[4266],{"type":46,"value":265},{"type":41,"tag":523,"props":4268,"children":4269},{"style":552},[4270],{"type":46,"value":1448},{"type":41,"tag":523,"props":4272,"children":4273},{"style":546},[4274],{"type":46,"value":842},{"type":41,"tag":523,"props":4276,"children":4277},{"class":525,"line":1455},[4278,4282,4286],{"type":41,"tag":523,"props":4279,"children":4280},{"style":546},[4281],{"type":46,"value":1484},{"type":41,"tag":523,"props":4283,"children":4284},{"style":787},[4285],{"type":46,"value":638},{"type":41,"tag":523,"props":4287,"children":4288},{"style":546},[4289],{"type":46,"value":586},{"type":41,"tag":523,"props":4291,"children":4292},{"class":525,"line":1478},[4293,4297],{"type":41,"tag":523,"props":4294,"children":4295},{"style":540},[4296],{"type":46,"value":1343},{"type":41,"tag":523,"props":4298,"children":4299},{"style":546},[4300],{"type":46,"value":2929},{"type":41,"tag":523,"props":4302,"children":4303},{"class":525,"line":1495},[4304],{"type":41,"tag":523,"props":4305,"children":4306},{"style":546},[4307],{"type":46,"value":1501},{"type":41,"tag":523,"props":4309,"children":4310},{"class":525,"line":1504},[4311,4315,4319],{"type":41,"tag":523,"props":4312,"children":4313},{"style":546},[4314],{"type":46,"value":1005},{"type":41,"tag":523,"props":4316,"children":4317},{"style":552},[4318],{"type":46,"value":638},{"type":41,"tag":523,"props":4320,"children":4321},{"style":546},[4322],{"type":46,"value":586},{"type":41,"tag":3477,"props":4324,"children":4326},{"id":4325},"ids-across-the-boundary",[4327],{"type":46,"value":4328},"IDs across the boundary",{"type":41,"tag":512,"props":4330,"children":4332},{"className":514,"code":4331,"language":516,"meta":517,"style":517},"\u002F\u002F Bad: parent app table IDs are not valid component validators\nargs: {\n  userId: v.id(\"users\"),\n}\n",[4333],{"type":41,"tag":111,"props":4334,"children":4335},{"__ignoreMap":517},[4336,4344,4360,4408],{"type":41,"tag":523,"props":4337,"children":4338},{"class":525,"line":526},[4339],{"type":41,"tag":523,"props":4340,"children":4341},{"style":530},[4342],{"type":46,"value":4343},"\u002F\u002F Bad: parent app table IDs are not valid component validators\n",{"type":41,"tag":523,"props":4345,"children":4346},{"class":525,"line":536},[4347,4352,4356],{"type":41,"tag":523,"props":4348,"children":4350},{"style":4349},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[4351],{"type":46,"value":3459},{"type":41,"tag":523,"props":4353,"children":4354},{"style":546},[4355],{"type":46,"value":795},{"type":41,"tag":523,"props":4357,"children":4358},{"style":546},[4359],{"type":46,"value":1335},{"type":41,"tag":523,"props":4361,"children":4362},{"class":525,"line":589},[4363,4367,4371,4375,4379,4383,4387,4391,4396,4400,4404],{"type":41,"tag":523,"props":4364,"children":4365},{"style":4349},[4366],{"type":46,"value":3762},{"type":41,"tag":523,"props":4368,"children":4369},{"style":546},[4370],{"type":46,"value":795},{"type":41,"tag":523,"props":4372,"children":4373},{"style":552},[4374],{"type":46,"value":723},{"type":41,"tag":523,"props":4376,"children":4377},{"style":546},[4378],{"type":46,"value":265},{"type":41,"tag":523,"props":4380,"children":4381},{"style":613},[4382],{"type":46,"value":1260},{"type":41,"tag":523,"props":4384,"children":4385},{"style":787},[4386],{"type":46,"value":620},{"type":41,"tag":523,"props":4388,"children":4389},{"style":546},[4390],{"type":46,"value":581},{"type":41,"tag":523,"props":4392,"children":4393},{"style":573},[4394],{"type":46,"value":4395},"users",{"type":41,"tag":523,"props":4397,"children":4398},{"style":546},[4399],{"type":46,"value":581},{"type":41,"tag":523,"props":4401,"children":4402},{"style":787},[4403],{"type":46,"value":638},{"type":41,"tag":523,"props":4405,"children":4406},{"style":546},[4407],{"type":46,"value":842},{"type":41,"tag":523,"props":4409,"children":4410},{"class":525,"line":599},[4411],{"type":41,"tag":523,"props":4412,"children":4413},{"style":546},[4414],{"type":46,"value":4415},"}\n",{"type":41,"tag":512,"props":4417,"children":4419},{"className":514,"code":4418,"language":516,"meta":517,"style":517},"\u002F\u002F Good: treat parent-owned IDs as strings at the boundary\nargs: {\n  userId: v.string(),\n}\n",[4420],{"type":41,"tag":111,"props":4421,"children":4422},{"__ignoreMap":517},[4423,4431,4446,4477],{"type":41,"tag":523,"props":4424,"children":4425},{"class":525,"line":526},[4426],{"type":41,"tag":523,"props":4427,"children":4428},{"style":530},[4429],{"type":46,"value":4430},"\u002F\u002F Good: treat parent-owned IDs as strings at the boundary\n",{"type":41,"tag":523,"props":4432,"children":4433},{"class":525,"line":536},[4434,4438,4442],{"type":41,"tag":523,"props":4435,"children":4436},{"style":4349},[4437],{"type":46,"value":3459},{"type":41,"tag":523,"props":4439,"children":4440},{"style":546},[4441],{"type":46,"value":795},{"type":41,"tag":523,"props":4443,"children":4444},{"style":546},[4445],{"type":46,"value":1335},{"type":41,"tag":523,"props":4447,"children":4448},{"class":525,"line":589},[4449,4453,4457,4461,4465,4469,4473],{"type":41,"tag":523,"props":4450,"children":4451},{"style":4349},[4452],{"type":46,"value":3762},{"type":41,"tag":523,"props":4454,"children":4455},{"style":546},[4456],{"type":46,"value":795},{"type":41,"tag":523,"props":4458,"children":4459},{"style":552},[4460],{"type":46,"value":723},{"type":41,"tag":523,"props":4462,"children":4463},{"style":546},[4464],{"type":46,"value":265},{"type":41,"tag":523,"props":4466,"children":4467},{"style":613},[4468],{"type":46,"value":832},{"type":41,"tag":523,"props":4470,"children":4471},{"style":787},[4472],{"type":46,"value":837},{"type":41,"tag":523,"props":4474,"children":4475},{"style":546},[4476],{"type":46,"value":842},{"type":41,"tag":523,"props":4478,"children":4479},{"class":525,"line":599},[4480],{"type":41,"tag":523,"props":4481,"children":4482},{"style":546},[4483],{"type":46,"value":4415},{"type":41,"tag":3477,"props":4485,"children":4487},{"id":4486},"advanced-patterns",[4488],{"type":46,"value":4489},"Advanced Patterns",{"type":41,"tag":49,"props":4491,"children":4492},{},[4493,4495,4501],{"type":46,"value":4494},"For additional patterns including function handles for callbacks, deriving\nvalidators from schema, static configuration with a globals table, and\nclass-based client wrappers, see ",{"type":41,"tag":111,"props":4496,"children":4498},{"className":4497},[],[4499],{"type":46,"value":4500},"references\u002Fadvanced-patterns.md",{"type":46,"value":265},{"type":41,"tag":55,"props":4503,"children":4505},{"id":4504},"validation",[4506],{"type":46,"value":4507},"Validation",{"type":41,"tag":49,"props":4509,"children":4510},{},[4511],{"type":46,"value":4512},"Try validation in this order:",{"type":41,"tag":129,"props":4514,"children":4515},{},[4516,4525,4534],{"type":41,"tag":66,"props":4517,"children":4518},{},[4519],{"type":41,"tag":111,"props":4520,"children":4522},{"className":4521},[],[4523],{"type":46,"value":4524},"npx convex codegen --component-dir convex\u002Fcomponents\u002F\u003Cname>",{"type":41,"tag":66,"props":4526,"children":4527},{},[4528],{"type":41,"tag":111,"props":4529,"children":4531},{"className":4530},[],[4532],{"type":46,"value":4533},"npx convex codegen",{"type":41,"tag":66,"props":4535,"children":4536},{},[4537],{"type":41,"tag":111,"props":4538,"children":4540},{"className":4539},[],[4541],{"type":46,"value":281},{"type":41,"tag":49,"props":4543,"children":4544},{},[4545],{"type":46,"value":4546},"Important:",{"type":41,"tag":62,"props":4548,"children":4549},{},[4550,4563,4584],{"type":41,"tag":66,"props":4551,"children":4552},{},[4553,4555,4561],{"type":46,"value":4554},"Fresh repos may fail these commands until ",{"type":41,"tag":111,"props":4556,"children":4558},{"className":4557},[],[4559],{"type":46,"value":4560},"CONVEX_DEPLOYMENT",{"type":46,"value":4562}," is configured.",{"type":41,"tag":66,"props":4564,"children":4565},{},[4566,4568,4574,4576,4582],{"type":46,"value":4567},"Until codegen runs, component-local ",{"type":41,"tag":111,"props":4569,"children":4571},{"className":4570},[],[4572],{"type":46,"value":4573},".\u002F_generated\u002F*",{"type":46,"value":4575}," imports and app-side\n",{"type":41,"tag":111,"props":4577,"children":4579},{"className":4578},[],[4580],{"type":46,"value":4581},"components.\u003Cname>...",{"type":46,"value":4583}," references will not typecheck.",{"type":41,"tag":66,"props":4585,"children":4586},{},[4587],{"type":46,"value":4588},"If validation blocks on Convex login or deployment setup, stop and ask the\nuser for that exact step instead of guessing.",{"type":41,"tag":55,"props":4590,"children":4592},{"id":4591},"reference-files",[4593],{"type":46,"value":4594},"Reference Files",{"type":41,"tag":49,"props":4596,"children":4597},{},[4598],{"type":46,"value":4599},"Read exactly one of these after the user confirms the goal:",{"type":41,"tag":62,"props":4601,"children":4602},{},[4603,4611,4619],{"type":41,"tag":66,"props":4604,"children":4605},{},[4606],{"type":41,"tag":111,"props":4607,"children":4609},{"className":4608},[],[4610],{"type":46,"value":349},{"type":41,"tag":66,"props":4612,"children":4613},{},[4614],{"type":41,"tag":111,"props":4615,"children":4617},{"className":4616},[],[4618],{"type":46,"value":371},{"type":41,"tag":66,"props":4620,"children":4621},{},[4622],{"type":41,"tag":111,"props":4623,"children":4625},{"className":4624},[],[4626],{"type":46,"value":393},{"type":41,"tag":49,"props":4628,"children":4629},{},[4630,4632],{"type":46,"value":4631},"Official docs:\n",{"type":41,"tag":4633,"props":4634,"children":4638},"a",{"href":4635,"rel":4636},"https:\u002F\u002Fdocs.convex.dev\u002Fcomponents\u002Fauthoring",[4637],"nofollow",[4639],{"type":46,"value":4640},"Authoring Components",{"type":41,"tag":55,"props":4642,"children":4644},{"id":4643},"checklist",[4645],{"type":46,"value":4646},"Checklist",{"type":41,"tag":62,"props":4648,"children":4651},{"className":4649},[4650],"contains-task-list",[4652,4664,4673,4682,4691,4708,4722,4731,4746,4768],{"type":41,"tag":66,"props":4653,"children":4656},{"className":4654},[4655],"task-list-item",[4657,4662],{"type":41,"tag":4658,"props":4659,"children":4661},"input",{"disabled":593,"type":4660},"checkbox",[],{"type":46,"value":4663}," Asked the user what they want to build and confirmed the shape",{"type":41,"tag":66,"props":4665,"children":4667},{"className":4666},[4655],[4668,4671],{"type":41,"tag":4658,"props":4669,"children":4670},{"disabled":593,"type":4660},[],{"type":46,"value":4672}," Read the matching reference file",{"type":41,"tag":66,"props":4674,"children":4676},{"className":4675},[4655],[4677,4680],{"type":41,"tag":4658,"props":4678,"children":4679},{"disabled":593,"type":4660},[],{"type":46,"value":4681}," Confirmed a component is the right abstraction",{"type":41,"tag":66,"props":4683,"children":4685},{"className":4684},[4655],[4686,4689],{"type":41,"tag":4658,"props":4687,"children":4688},{"disabled":593,"type":4660},[],{"type":46,"value":4690}," Planned tables, public API, boundaries, and app wrappers",{"type":41,"tag":66,"props":4692,"children":4694},{"className":4693},[4655],[4695,4698,4700,4706],{"type":41,"tag":4658,"props":4696,"children":4697},{"disabled":593,"type":4660},[],{"type":46,"value":4699}," Component lives under ",{"type":41,"tag":111,"props":4701,"children":4703},{"className":4702},[],[4704],{"type":46,"value":4705},"convex\u002Fcomponents\u002F\u003Cname>\u002F",{"type":46,"value":4707}," (or package layout if\npublishing)",{"type":41,"tag":66,"props":4709,"children":4711},{"className":4710},[4655],[4712,4715,4717],{"type":41,"tag":4658,"props":4713,"children":4714},{"disabled":593,"type":4660},[],{"type":46,"value":4716}," Component imports from its own ",{"type":41,"tag":111,"props":4718,"children":4720},{"className":4719},[],[4721],{"type":46,"value":206},{"type":41,"tag":66,"props":4723,"children":4725},{"className":4724},[4655],[4726,4729],{"type":41,"tag":4658,"props":4727,"children":4728},{"disabled":593,"type":4660},[],{"type":46,"value":4730}," Auth, env access, and HTTP routes stay in the app",{"type":41,"tag":66,"props":4732,"children":4734},{"className":4733},[4655],[4735,4738,4740],{"type":41,"tag":4658,"props":4736,"children":4737},{"disabled":593,"type":4660},[],{"type":46,"value":4739}," Parent app IDs cross the boundary as ",{"type":41,"tag":111,"props":4741,"children":4743},{"className":4742},[],[4744],{"type":46,"value":4745},"v.string()",{"type":41,"tag":66,"props":4747,"children":4749},{"className":4748},[4655],[4750,4753,4755,4760,4761,4766],{"type":41,"tag":4658,"props":4751,"children":4752},{"disabled":593,"type":4660},[],{"type":46,"value":4754}," Public functions have ",{"type":41,"tag":111,"props":4756,"children":4758},{"className":4757},[],[4759],{"type":46,"value":3459},{"type":46,"value":3461},{"type":41,"tag":111,"props":4762,"children":4764},{"className":4763},[],[4765],{"type":46,"value":3467},{"type":46,"value":4767}," validators",{"type":41,"tag":66,"props":4769,"children":4771},{"className":4770},[4655],[4772,4775,4777,4782],{"type":41,"tag":4658,"props":4773,"children":4774},{"disabled":593,"type":4660},[],{"type":46,"value":4776}," Ran ",{"type":41,"tag":111,"props":4778,"children":4780},{"className":4779},[],[4781],{"type":46,"value":281},{"type":46,"value":4783}," and fixed codegen or type issues",{"type":41,"tag":4785,"props":4786,"children":4787},"style",{},[4788],{"type":46,"value":4789},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":4791,"total":783},[4792,4803,4810,4825,4842,4859],{"slug":8,"name":8,"fn":4793,"description":4794,"org":4795,"tags":4796,"stars":24,"repoUrl":25,"updatedAt":4802},"guide Convex project setup and usage","Routes general Convex requests to the right project skill. Use when the user asks which Convex skill to use or gives an underspecified Convex app task.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4797,4798,4799],{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"name":4800,"slug":4801,"type":16},"Database","database","2026-07-12T08:00:45.091281",{"slug":4,"name":4,"fn":5,"description":6,"org":4804,"tags":4805,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4806,4807,4808,4809],{"name":22,"slug":23,"type":16},{"name":19,"slug":20,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"slug":4811,"name":4811,"fn":4812,"description":4813,"org":4814,"tags":4815,"stars":24,"repoUrl":25,"updatedAt":4824},"convex-migration-helper","plan Convex schema and data migrations","Plans Convex schema and data migrations with widen-migrate-narrow and @convex-dev\u002Fmigrations. Use for breaking schema changes, backfills, table reshaping, or zero-downtime rollouts.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4816,4817,4818,4821],{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"name":4819,"slug":4820,"type":16},"Data Engineering","data-engineering",{"name":4822,"slug":4823,"type":16},"Migration","migration","2026-07-12T08:00:51.27967",{"slug":4826,"name":4826,"fn":4827,"description":4828,"org":4829,"tags":4830,"stars":24,"repoUrl":25,"updatedAt":4841},"convex-performance-audit","audit Convex application performance","Audits Convex performance for reads, subscriptions, write contention, and function limits. Use for slow features, insights findings, OCC conflicts, or read amplification.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4831,4832,4835,4838],{"name":9,"slug":8,"type":16},{"name":4833,"slug":4834,"type":16},"Debugging","debugging",{"name":4836,"slug":4837,"type":16},"Monitoring","monitoring",{"name":4839,"slug":4840,"type":16},"Performance","performance","2026-07-12T08:00:50.02928",{"slug":4843,"name":4843,"fn":4844,"description":4845,"org":4846,"tags":4847,"stars":24,"repoUrl":25,"updatedAt":4858},"convex-quickstart","initialize Convex in applications","Creates or adds Convex to an app. Use for new Convex projects, npm create convex@latest, frontend setup, env vars, or the first npx convex dev run.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4848,4851,4852,4855],{"name":4849,"slug":4850,"type":16},"CLI","cli",{"name":9,"slug":8,"type":16},{"name":4853,"slug":4854,"type":16},"Frontend","frontend",{"name":4856,"slug":4857,"type":16},"Onboarding","onboarding","2026-07-12T08:00:43.436152",{"slug":4860,"name":4860,"fn":4861,"description":4862,"org":4863,"tags":4864,"stars":24,"repoUrl":25,"updatedAt":4872},"convex-setup-auth","set up authentication and access control","Sets up Convex auth, identity mapping, and access control. Use for login, auth providers, users tables, protected functions, or roles in a Convex app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4865,4868,4870,4871],{"name":4866,"slug":4867,"type":16},"Access Control","access-control",{"name":4869,"slug":3530,"type":16},"Auth",{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},"2026-07-12T08:00:48.652641",{"items":4874,"total":1840},[4875,4881,4888,4895,4902,4909,4916,4929,4948,4962,4979,4993],{"slug":8,"name":8,"fn":4793,"description":4794,"org":4876,"tags":4877,"stars":24,"repoUrl":25,"updatedAt":4802},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4878,4879,4880],{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"name":4800,"slug":4801,"type":16},{"slug":4,"name":4,"fn":5,"description":6,"org":4882,"tags":4883,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4884,4885,4886,4887],{"name":22,"slug":23,"type":16},{"name":19,"slug":20,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"slug":4811,"name":4811,"fn":4812,"description":4813,"org":4889,"tags":4890,"stars":24,"repoUrl":25,"updatedAt":4824},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4891,4892,4893,4894],{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"name":4819,"slug":4820,"type":16},{"name":4822,"slug":4823,"type":16},{"slug":4826,"name":4826,"fn":4827,"description":4828,"org":4896,"tags":4897,"stars":24,"repoUrl":25,"updatedAt":4841},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4898,4899,4900,4901],{"name":9,"slug":8,"type":16},{"name":4833,"slug":4834,"type":16},{"name":4836,"slug":4837,"type":16},{"name":4839,"slug":4840,"type":16},{"slug":4843,"name":4843,"fn":4844,"description":4845,"org":4903,"tags":4904,"stars":24,"repoUrl":25,"updatedAt":4858},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4905,4906,4907,4908],{"name":4849,"slug":4850,"type":16},{"name":9,"slug":8,"type":16},{"name":4853,"slug":4854,"type":16},{"name":4856,"slug":4857,"type":16},{"slug":4860,"name":4860,"fn":4861,"description":4862,"org":4910,"tags":4911,"stars":24,"repoUrl":25,"updatedAt":4872},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4912,4913,4914,4915],{"name":4866,"slug":4867,"type":16},{"name":4869,"slug":3530,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"slug":4917,"name":4917,"fn":4918,"description":4919,"org":4920,"tags":4921,"stars":536,"repoUrl":4927,"updatedAt":4928},"add","add capabilities to Convex applications","Add a capability to the CURRENT Convex + Next.js project — consults the served Convex capability catalog for always-current procedures (billing, crons, auth, agent, search, …); falls back to built-in hosting or @convex-dev component search. TRIGGER when the user runs $add, or asks to add hosting\u002Fpublishing or any backend capability to an existing Convex app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4922,4923,4924],{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"name":4925,"slug":4926,"type":16},"Next.js","next-js","https:\u002F\u002Fgithub.com\u002Fget-convex\u002Fconvex-codex-plugin","2026-07-12T07:59:59.358004",{"slug":4930,"name":4930,"fn":4931,"description":4932,"org":4933,"tags":4934,"stars":536,"repoUrl":4927,"updatedAt":4947},"agent","build AI agents with Convex","Build an AI agent \u002F RAG feature on Convex (@convex-dev\u002Fagent: threads, tools, vector search). TRIGGER on an AI-agent\u002Fchatbot\u002FRAG request.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4935,4938,4941,4944],{"name":4936,"slug":4937,"type":16},"Agents","agents",{"name":4939,"slug":4940,"type":16},"Engineering","engineering",{"name":4942,"slug":4943,"type":16},"RAG","rag",{"name":4945,"slug":4946,"type":16},"Search","search","2026-07-12T08:00:01.921824",{"slug":3530,"name":3530,"fn":4949,"description":4950,"org":4951,"tags":4952,"stars":536,"repoUrl":4927,"updatedAt":4961},"add authentication to Convex applications","Add sign-in (passkeys by default, OAuth\u002Fpassword optional) to the current Convex app, wired correctly incl. auth.config.ts. TRIGGER on a login\u002Fauth request for an existing app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4953,4954,4957,4958],{"name":4869,"slug":3530,"type":16},{"name":4955,"slug":4956,"type":16},"Authentication","authentication",{"name":9,"slug":8,"type":16},{"name":4959,"slug":4960,"type":16},"OAuth","oauth","2026-07-18T05:12:54.443056",{"slug":4963,"name":4963,"fn":4964,"description":4965,"org":4966,"tags":4967,"stars":536,"repoUrl":4927,"updatedAt":4978},"billing","integrate Stripe billing in Convex apps","Add Stripe billing to a Convex app via @convex-dev\u002Fstripe (checkout + auto-verified webhook + subscription gating). TRIGGER on a payments\u002Fbilling\u002Fsubscription request.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4968,4969,4972,4975],{"name":9,"slug":8,"type":16},{"name":4970,"slug":4971,"type":16},"Payments","payments",{"name":4973,"slug":4974,"type":16},"Stripe","stripe",{"name":4976,"slug":4977,"type":16},"Webhooks","webhooks","2026-07-12T08:00:08.123246",{"slug":4980,"name":4980,"fn":4981,"description":4982,"org":4983,"tags":4984,"stars":536,"repoUrl":4927,"updatedAt":4992},"check-updates","upgrade Convex component versions","Check the CURRENT Convex app's pinned components against the latest recommended versions and offer to upgrade them — e.g. the passkey auth component's new email-first sign-in. TRIGGER when the user runs \u002Fcheck-updates or $check-updates, asks 'are my components up to date', 'any updates', 'upgrade auth', 'upgrade my components', or wants the newest features after a quickstart. Applies each upgrade behind a build gate (verify-or-revert) with the user's consent.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4985,4988,4989],{"name":4986,"slug":4987,"type":16},"Configuration","configuration",{"name":9,"slug":8,"type":16},{"name":4990,"slug":4991,"type":16},"Maintenance","maintenance","2026-07-12T08:00:03.236862",{"slug":4994,"name":4994,"fn":4995,"description":4996,"org":4997,"tags":4998,"stars":536,"repoUrl":4927,"updatedAt":5007},"convex-authz","audit and harden Convex authorization","Audit and harden a Convex app's authorization: identity-from-arg impersonation, missing per-document ownership checks, and public queries leaking PII\u002Ffinancial data by a client-supplied id — the single largest real-defect cluster measured against generated Convex backends (44 of 214). Runs a deterministic scan for the 3 shapes, then applies the canonical requireIdentity\u002FrequireOwner pattern, then verifies with tsc. TRIGGER on 'secure my app', 'audit auth', 'add login', 'who can access this data', or an explicit 'audit my authz'. NOT always-on. SKIP when there is no convex\u002F directory.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4999,5000,5003,5004],{"name":4869,"slug":3530,"type":16},{"name":5001,"slug":5002,"type":16},"Code Analysis","code-analysis",{"name":9,"slug":8,"type":16},{"name":5005,"slug":5006,"type":16},"Security","security","2026-07-12T08:00:04.516752"]