UNPKG

@oxyhq/services

Version:

OxyHQ Expo/React Native SDK — UI components, screens, and native features

177 lines (165 loc) 5.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createGenericMutation = createGenericMutation; exports.createProfileMutation = createProfileMutation; var _queryKeys = require("../queries/queryKeys.js"); var _sonner = require("../../../lib/sonner"); var _authStore = require("../../stores/authStore.js"); /** * Mutation Factory - Creates standardized mutations with optimistic updates * * This factory reduces boilerplate code for mutations that follow the common pattern: * 1. Cancel outgoing queries * 2. Snapshot previous data * 3. Apply optimistic update * 4. On error: rollback and show toast * 5. On success: update cache, stores, and invalidate queries */ /** * Configuration for creating a standard profile mutation */ /** * Creates a standard profile mutation with optimistic updates * * @example * ```ts * const updateProfile = createProfileMutation({ * mutationFn: (updates) => oxyServices.updateProfile(updates), * optimisticUpdate: (user, updates) => updates, * errorMessage: 'Failed to update profile', * }); * ``` */ function createProfileMutation(config, queryClient, activeSessionId) { const { mutationFn, cancelQueryKeys = [], optimisticUpdate, errorMessage = 'Operation failed', successMessage, updateAuthStore = true, invalidateUserQueries: shouldInvalidateUserQueries = true, invalidateAccountQueries: shouldInvalidateAccountQueries = true, onSuccess: customOnSuccess } = config; return { mutationFn, onMutate: async variables => { // Cancel queries that might conflict await queryClient.cancelQueries({ queryKey: _queryKeys.queryKeys.accounts.current() }); for (const key of cancelQueryKeys) { await queryClient.cancelQueries({ queryKey: key }); } // Snapshot previous user data const previousUser = queryClient.getQueryData(_queryKeys.queryKeys.accounts.current()); // Apply optimistic update if provided if (previousUser && optimisticUpdate) { const updates = optimisticUpdate(previousUser, variables); const optimisticUser = { ...previousUser, ...updates }; queryClient.setQueryData(_queryKeys.queryKeys.accounts.current(), optimisticUser); if (activeSessionId) { queryClient.setQueryData(_queryKeys.queryKeys.users.profile(activeSessionId), optimisticUser); } } return { previousUser }; }, onError: (error, _variables, context) => { // Rollback optimistic update if (context?.previousUser) { queryClient.setQueryData(_queryKeys.queryKeys.accounts.current(), context.previousUser); if (activeSessionId) { queryClient.setQueryData(_queryKeys.queryKeys.users.profile(activeSessionId), context.previousUser); } } // Show error toast const message = typeof errorMessage === 'function' ? errorMessage(error) : error instanceof Error ? error.message : errorMessage; _sonner.toast.error(message); }, onSuccess: (data, variables) => { // Update cache with server response queryClient.setQueryData(_queryKeys.queryKeys.accounts.current(), data); if (activeSessionId) { queryClient.setQueryData(_queryKeys.queryKeys.users.profile(activeSessionId), data); } // Update authStore for immediate UI updates if (updateAuthStore) { _authStore.useAuthStore.getState().setUser(data); } // Invalidate related queries if (shouldInvalidateUserQueries) { (0, _queryKeys.invalidateUserQueries)(queryClient); } if (shouldInvalidateAccountQueries) { (0, _queryKeys.invalidateAccountQueries)(queryClient); } // Show success toast if configured if (successMessage) { _sonner.toast.success(successMessage); } // Call custom onSuccess handler if (customOnSuccess) { customOnSuccess(data, variables, queryClient); } } }; } /** * Configuration for creating a generic mutation (non-profile) */ /** * Creates a generic mutation with optimistic updates */ function createGenericMutation(config, queryClient) { const { mutationFn, queryKey, optimisticData, errorMessage = 'Operation failed', successMessage, invalidateQueries = [] } = config; return { mutationFn, onMutate: async variables => { await queryClient.cancelQueries({ queryKey }); const previous = queryClient.getQueryData(queryKey); if (optimisticData) { queryClient.setQueryData(queryKey, optimisticData(previous, variables)); } return { previous }; }, onError: (error, _variables, context) => { if (context?.previous !== undefined) { queryClient.setQueryData(queryKey, context.previous); } _sonner.toast.error(error instanceof Error ? error.message : errorMessage); }, onSuccess: data => { queryClient.setQueryData(queryKey, data); for (const key of invalidateQueries) { queryClient.invalidateQueries({ queryKey: key }); } if (successMessage) { _sonner.toast.success(successMessage); } } }; } //# sourceMappingURL=mutationFactory.js.map