{"version":3,"file":"optimistic-action.cjs","sources":["../../src/optimistic-action.ts"],"sourcesContent":["import { createTransaction } from './transactions'\nimport { OnMutateMustBeSynchronousError } from './errors'\nimport { isPromiseLike } from './utils/type-guards'\nimport type { CreateOptimisticActionsOptions, Transaction } from './types'\n\n/**\n * Creates an optimistic action function that applies local optimistic updates immediately\n * before executing the actual mutation on the server.\n *\n * This pattern allows for responsive UI updates while the actual mutation is in progress.\n * The optimistic update is applied via the `onMutate` callback, and the server mutation\n * is executed via the `mutationFn`.\n *\n * **Important:** Inside your `mutationFn`, you must ensure that your server writes have synced back\n * before you return, as the optimistic state is dropped when you return from the mutation function.\n * You generally use collection-specific helpers to do this, such as Query's `utils.refetch()`,\n * direct write APIs, or Electric's `utils.awaitTxId()`.\n *\n * @example\n * ```ts\n * const addTodo = createOptimisticAction<string>({\n *   onMutate: (text) => {\n *     // Instantly applies local optimistic state\n *     todoCollection.insert({\n *       id: uuid(),\n *       text,\n *       completed: false\n *     })\n *   },\n *   mutationFn: async (text, params) => {\n *     // Persist the todo to your backend\n *     const response = await fetch('/api/todos', {\n *       method: 'POST',\n *       body: JSON.stringify({ text, completed: false }),\n *     })\n *     const result = await response.json()\n *\n *     // IMPORTANT: Ensure server writes have synced back before returning\n *     // This ensures the optimistic state can be safely discarded\n *     await todoCollection.utils.refetch()\n *\n *     return result\n *   }\n * })\n *\n * // Usage\n * const transaction = addTodo('New Todo Item')\n * ```\n *\n * @template TVariables - The type of variables that will be passed to the action function\n * @param options - Configuration options for the optimistic action\n * @returns A function that accepts variables of type TVariables and returns a Transaction\n */\nexport function createOptimisticAction<TVariables = unknown>(\n  options: CreateOptimisticActionsOptions<TVariables>,\n) {\n  const { mutationFn, onMutate, ...config } = options\n\n  return (variables: TVariables): Transaction => {\n    // Create transaction with the original config\n    const transaction = createTransaction({\n      ...config,\n      // Wire the mutationFn to use the provided variables\n      mutationFn: async (params) => {\n        return await mutationFn(variables, params)\n      },\n    })\n\n    // Execute the transaction. The mutationFn is called once mutate()\n    // is finished.\n    transaction.mutate(() => {\n      const maybePromise = onMutate(variables) as unknown\n\n      if (isPromiseLike(maybePromise)) {\n        throw new OnMutateMustBeSynchronousError()\n      }\n    })\n\n    return transaction\n  }\n}\n"],"names":["createTransaction","isPromiseLike","OnMutateMustBeSynchronousError"],"mappings":";;;;;AAqDO,SAAS,uBACd,SACA;AACA,QAAM,EAAE,YAAY,UAAU,GAAG,WAAW;AAE5C,SAAO,CAAC,cAAuC;AAE7C,UAAM,cAAcA,aAAAA,kBAAkB;AAAA,MACpC,GAAG;AAAA;AAAA,MAEH,YAAY,OAAO,WAAW;AAC5B,eAAO,MAAM,WAAW,WAAW,MAAM;AAAA,MAC3C;AAAA,IAAA,CACD;AAID,gBAAY,OAAO,MAAM;AACvB,YAAM,eAAe,SAAS,SAAS;AAEvC,UAAIC,WAAAA,cAAc,YAAY,GAAG;AAC/B,cAAM,IAAIC,OAAAA,+BAAA;AAAA,MACZ;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AACF;;"}