diff --git a/eslint.config.js b/eslint.config.js index 4cd2123..76ef82e 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -3,6 +3,7 @@ import pluginJs from "@eslint/js"; import tseslint from "typescript-eslint"; import reactHooks from "eslint-plugin-react-hooks"; import reactRefresh from "eslint-plugin-react-refresh"; +import convexPlugin from "@convex-dev/eslint-plugin"; export default [ { @@ -36,7 +37,12 @@ export default [ languageOptions: { globals: globals.worker, }, + plugins: { + "@convex-dev": convexPlugin, + }, rules: { + ...convexPlugin.configs.recommended[0].rules, + "@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/no-explicit-any": "off", "no-unused-vars": "off", diff --git a/example/convex/messages.ts b/example/convex/messages.ts index 1694d38..c34f5c4 100644 --- a/example/convex/messages.ts +++ b/example/convex/messages.ts @@ -14,7 +14,7 @@ export const clearMessages = mutation({ args: {}, handler: async (ctx) => { const chats = await ctx.db.query("userMessages").collect(); - await Promise.all(chats.map((chat) => ctx.db.delete(chat._id))); + await Promise.all(chats.map((chat) => ctx.db.delete("userMessages", chat._id))); }, }); diff --git a/package-lock.json b/package-lock.json index c7c20a5..dcabd83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "convex-helpers": "^0.1.114" }, "devDependencies": { + "@convex-dev/eslint-plugin": "^2.0.0", "@edge-runtime/vm": "5.0.0", "@eslint/eslintrc": "3.3.5", "@eslint/js": "9.39.4", @@ -326,6 +327,20 @@ "node": ">=6.9.0" } }, + "node_modules/@convex-dev/eslint-plugin": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@convex-dev/eslint-plugin/-/eslint-plugin-2.0.0.tgz", + "integrity": "sha512-GxYe0b5RoAb7c7JzcAX3t+UrdT6edQDtSgJ2F9UPECLyQGU0TeTkyGsDXNm3HK+MnWYi8isRlqaqoYTUD0Ko+Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@typescript-eslint/types": "~8.58.0", + "@typescript-eslint/utils": "~8.58.0" + }, + "peerDependencies": { + "convex": "^1.34.1" + } + }, "node_modules/@edge-runtime/primitives": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-6.0.0.tgz", diff --git a/package.json b/package.json index 5d479ef..7d3371f 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "react-dom": "~18.3.1 || ^19.0.0" }, "devDependencies": { + "@convex-dev/eslint-plugin": "^2.0.0", "@edge-runtime/vm": "5.0.0", "@eslint/eslintrc": "3.3.5", "@eslint/js": "9.39.4", diff --git a/src/component/lib.ts b/src/component/lib.ts index 78a81af..89931d0 100644 --- a/src/component/lib.ts +++ b/src/component/lib.ts @@ -25,12 +25,12 @@ export const addChunk = mutation({ final: v.boolean(), }, handler: async (ctx, args) => { - const stream = await ctx.db.get(args.streamId); + const stream = await ctx.db.get("streams", args.streamId); if (!stream) { throw new Error("Stream not found"); } if (stream.status === "pending") { - await ctx.db.patch(args.streamId, { + await ctx.db.patch("streams", args.streamId, { status: "streaming", }); } else if (stream.status !== "streaming") { @@ -41,7 +41,7 @@ export const addChunk = mutation({ text: args.text, }); if (args.final) { - await ctx.db.patch(args.streamId, { + await ctx.db.patch("streams", args.streamId, { status: "done", }); } @@ -62,7 +62,7 @@ export const setStreamStatus = mutation({ ), }, handler: async (ctx, args) => { - const stream = await ctx.db.get(args.streamId); + const stream = await ctx.db.get("streams", args.streamId); if (!stream) { throw new Error("Stream not found"); } @@ -73,7 +73,7 @@ export const setStreamStatus = mutation({ ); return; } - await ctx.db.patch(args.streamId, { + await ctx.db.patch("streams", args.streamId, { status: args.status, }); }, @@ -86,7 +86,7 @@ export const getStreamStatus = query({ }, returns: streamStatusValidator, handler: async (ctx, args) => { - const stream = await ctx.db.get(args.streamId); + const stream = await ctx.db.get("streams", args.streamId); return stream?.status ?? "error"; }, }); @@ -102,7 +102,7 @@ export const getStreamText = query({ status: streamStatusValidator, }), handler: async (ctx, args) => { - const stream = await ctx.db.get(args.streamId); + const stream = await ctx.db.get("streams", args.streamId); if (!stream) { throw new Error("Stream not found"); } @@ -133,11 +133,11 @@ export const deleteStream = mutation({ }, returns: v.null(), handler: async (ctx, args) => { - const stream = await ctx.db.get(args.streamId); + const stream = await ctx.db.get("streams", args.streamId); if (!stream) { throw new Error(`Stream ${args.streamId} not found`); } - await ctx.db.delete(args.streamId); + await ctx.db.delete("streams", args.streamId); await ctx.scheduler.runAfter(0, internal.lib._deleteChunksPage, { streamId: args.streamId, cursor: null, @@ -158,7 +158,7 @@ export const _deleteChunksPage = internalMutation({ .withIndex("byStream", (q) => q.eq("streamId", args.streamId)) .paginate({ cursor: args.cursor, numItems: DELETE_BATCH_SIZE }); - await Promise.all(result.page.map((chunk) => ctx.db.delete(chunk._id))); + await Promise.all(result.page.map((chunk) => ctx.db.delete("chunks", chunk._id))); if (!result.isDone) { await ctx.scheduler.runAfter(0, internal.lib._deleteChunksPage, { @@ -187,7 +187,7 @@ export const cleanupExpiredStreams = internalMutation({ for (const stream of [...pendingStreams, ...streamingStreams]) { if (now - stream._creationTime > EXPIRATION_TIME) { console.log("Cleaning up expired stream", stream._id); - await ctx.db.patch(stream._id, { + await ctx.db.patch("streams", stream._id, { status: "timeout", }); }