@@ -253,34 +253,153 @@ export interface Evolu<S extends EvoluSchema = EvoluSchema> {
253253 readonly getSyncState : ( ) => SyncState ;
254254
255255 /**
256- * Inserts a row.
256+ * Inserts a row into the database and returns a {@link Result} with the new
257+ * {@link Id}.
258+ *
259+ * The first argument is the table name, and the second is an object
260+ * containing the row data. An optional third argument provides mutation
261+ * options including an `onComplete` callback and `onlyValidate` flag.
262+ *
263+ * Returns a Result type - use `.ok` to check if the insertion succeeded, and
264+ * `.value.id` to access the generated ID on success, or `.error` to handle
265+ * validation errors.
266+ *
267+ * Evolu does not use SQL for mutations to ensure data can be safely and
268+ * predictably merged without conflicts.
269+ *
270+ * Explicit mutations also allow Evolu to automatically add and update a few
271+ * useful columns common to all tables. Those columns are: `createdAt`,
272+ * `updatedAt`, and `isDeleted`.
257273 *
258274 * ### Example
259275 *
260276 * ```ts
261- * // TODO:
277+ * const result = evolu.insert("todo", {
278+ * title: "Learn Evolu",
279+ * isCompleted: false,
280+ * });
281+ *
282+ * if (result.ok) {
283+ * console.log("Todo created with ID:", result.value.id);
284+ * } else {
285+ * console.error("Validation error:", result.error);
286+ * }
287+ *
288+ * // With onComplete callback
289+ * evolu.insert(
290+ * "todo",
291+ * { title: "Another todo" },
292+ * {
293+ * onComplete: () => {
294+ * console.log("Insert completed");
295+ * },
296+ * },
297+ * );
262298 * ```
263299 */
264300 insert : Mutation < S , "insert" > ;
265301
266302 /**
267- * Updates a row.
303+ * Updates a row in the database and returns a Result with the existing ID.
304+ *
305+ * The first argument is the table name, and the second is an object
306+ * containing the row data including the required `id` field. An optional
307+ * third argument provides mutation options including an `onComplete` callback
308+ * and `onlyValidate` flag.
309+ *
310+ * Returns a Result type - use `.ok` to check if the update succeeded, and
311+ * `.value.id` to access the ID on success, or `.error` to handle validation
312+ * errors.
313+ *
314+ * Evolu does not use SQL for mutations to ensure data can be safely and
315+ * predictably merged without conflicts.
316+ *
317+ * Explicit mutations also allow Evolu to automatically add and update a few
318+ * useful columns common to all tables. Those columns are: `createdAt`,
319+ * `updatedAt`, and `isDeleted`.
268320 *
269321 * ### Example
270322 *
271323 * ```ts
272- * // TODO:
324+ * const result = evolu.update("todo", {
325+ * id: todoId,
326+ * title: "Updated title",
327+ * isCompleted: true,
328+ * });
329+ *
330+ * if (result.ok) {
331+ * console.log("Todo updated with ID:", result.value.id);
332+ * } else {
333+ * console.error("Validation error:", result.error);
334+ * }
335+ *
336+ * // To delete a row, set isDeleted to true
337+ * evolu.update("todo", { id: todoId, isDeleted: true });
338+ *
339+ * // With onComplete callback
340+ * evolu.update(
341+ * "todo",
342+ * { id: todoId, title: "New title" },
343+ * {
344+ * onComplete: () => {
345+ * console.log("Update completed");
346+ * },
347+ * },
348+ * );
273349 * ```
274350 */
275351 update : Mutation < S , "update" > ;
276352
277353 /**
278- * Upserts a row.
354+ * Upserts a row in the database and returns a Result with the ID.
355+ *
356+ * The first argument is the table name, and the second is an object containing
357+ * the row data including the required `id` field. An optional third argument
358+ * provides mutation options including an `onComplete` callback and
359+ * `onlyValidate` flag.
360+ *
361+ * This function is useful when you already have an `id` and want to create a
362+ * new row or update an existing one in a single operation.
363+ *
364+ * Returns a Result type - use `.ok` to check if the upsert succeeded, and
365+ * `.value.id` to access the ID on success, or `.error` to handle validation
366+ * errors.
367+ *
368+ * Evolu does not use SQL for mutations to ensure data can be safely and
369+ * predictably merged without conflicts.
370+ *
371+ * Explicit mutations also allow Evolu to automatically add and update a few
372+ * useful columns common to all tables. Those columns are: `createdAt`,
373+ * `updatedAt`, and `isDeleted`.
279374 *
280375 * ### Example
281376 *
282377 * ```ts
283- * // TODO:
378+ * // Use deterministic ID for stable upserts
379+ * const stableId = createIdFromString("my-todo-1");
380+ *
381+ * const result = evolu.upsert("todo", {
382+ * id: stableId,
383+ * title: "Learn Evolu",
384+ * isCompleted: false,
385+ * });
386+ *
387+ * if (result.ok) {
388+ * console.log("Todo upserted with ID:", result.value.id);
389+ * } else {
390+ * console.error("Validation error:", result.error);
391+ * }
392+ *
393+ * // With onComplete callback
394+ * evolu.upsert(
395+ * "todo",
396+ * { id: stableId, title: "Updated title" },
397+ * {
398+ * onComplete: () => {
399+ * console.log("Upsert completed");
400+ * },
401+ * },
402+ * );
284403 * ```
285404 */
286405 upsert : Mutation < S , "upsert" > ;
@@ -635,6 +754,8 @@ const createEvoluInstance =
635754 const Type = getMutationType ( table , kind ) ;
636755 const result = Type . fromUnknown ( props ) ;
637756
757+ // upsert je ok?
758+
638759 const id =
639760 kind === "insert"
640761 ? createId ( deps )
0 commit comments