mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
72 lines
2.1 KiB
TypeScript
72 lines
2.1 KiB
TypeScript
import { ConvexError, v } from "convex/values";
|
|
import { mutation, query } from "./_generated/server";
|
|
import { CURRENT_PREFS_SCHEMA_VERSION, MAX_PREFS_BLOB_SIZE } from "./constants";
|
|
|
|
export const getPreferences = query({
|
|
args: { variant: v.string() },
|
|
handler: async (ctx, args) => {
|
|
const identity = await ctx.auth.getUserIdentity();
|
|
if (!identity) return null;
|
|
const userId = identity.subject;
|
|
return await ctx.db
|
|
.query("userPreferences")
|
|
.withIndex("by_user_variant", (q) =>
|
|
q.eq("userId", userId).eq("variant", args.variant),
|
|
)
|
|
.unique();
|
|
},
|
|
});
|
|
|
|
export const setPreferences = mutation({
|
|
args: {
|
|
variant: v.string(),
|
|
data: v.any(),
|
|
expectedSyncVersion: v.number(),
|
|
schemaVersion: v.optional(v.number()),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
const identity = await ctx.auth.getUserIdentity();
|
|
if (!identity) throw new ConvexError("UNAUTHENTICATED");
|
|
const userId = identity.subject;
|
|
|
|
const blobSize = JSON.stringify(args.data).length;
|
|
if (blobSize > MAX_PREFS_BLOB_SIZE) {
|
|
throw new ConvexError(`BLOB_TOO_LARGE: ${blobSize} > ${MAX_PREFS_BLOB_SIZE}`);
|
|
}
|
|
|
|
const existing = await ctx.db
|
|
.query("userPreferences")
|
|
.withIndex("by_user_variant", (q) =>
|
|
q.eq("userId", userId).eq("variant", args.variant),
|
|
)
|
|
.unique();
|
|
|
|
if (existing && existing.syncVersion !== args.expectedSyncVersion) {
|
|
throw new ConvexError("CONFLICT");
|
|
}
|
|
|
|
const nextSyncVersion = (existing?.syncVersion ?? 0) + 1;
|
|
const schemaVersion = args.schemaVersion ?? CURRENT_PREFS_SCHEMA_VERSION;
|
|
|
|
if (existing) {
|
|
await ctx.db.patch(existing._id, {
|
|
data: args.data,
|
|
schemaVersion,
|
|
updatedAt: Date.now(),
|
|
syncVersion: nextSyncVersion,
|
|
});
|
|
} else {
|
|
await ctx.db.insert("userPreferences", {
|
|
userId,
|
|
variant: args.variant,
|
|
data: args.data,
|
|
schemaVersion,
|
|
updatedAt: Date.now(),
|
|
syncVersion: nextSyncVersion,
|
|
});
|
|
}
|
|
|
|
return { syncVersion: nextSyncVersion };
|
|
},
|
|
});
|