react-query-external-sync
Version:
A tool for syncing React Query state to an external Dev Tools
187 lines • 9.54 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { log } from "./logger";
/**
* Unified storage handler that works with both MMKV and AsyncStorage
* This function updates the actual storage and then invalidates the React Query
*/
function handleStorageOperation(queryKey, data, queryClient, storageKey, storage, storageType, enableLogs, deviceName) {
return __awaiter(this, void 0, void 0, function* () {
try {
// Update the actual storage with the new data
if (data === null || data === undefined) {
// Delete the key if data is null/undefined
yield storage.delete(storageKey);
}
else if (typeof data === "string" ||
typeof data === "number" ||
typeof data === "boolean") {
// Handle primitives - both MMKV and AsyncStorage can handle these
// (AsyncStorage will convert numbers/booleans to strings automatically)
yield storage.set(storageKey, data);
}
else {
// For objects/arrays, JSON stringify for both storage types
const jsonString = JSON.stringify(data);
yield storage.set(storageKey, jsonString);
}
// Manually invalidate the React Query since programmatic storage updates
// don't trigger the change listener automatically
queryClient.invalidateQueries({ queryKey });
}
catch (error) {
log(`❌ Failed to update ${storageType} storage: ${error}`, enableLogs || false, "error");
// Fall back to just updating the query data if storage fails
queryClient.setQueryData(queryKey, data, {
updatedAt: Date.now(),
});
}
});
}
/**
* Unified storage removal handler that works with both MMKV and AsyncStorage
* This function removes the key from actual storage and removes the query from React Query cache
*/
function handleStorageRemovalOperation(queryKey, queryClient, storageKey, storage, storageType, enableLogs, deviceName) {
return __awaiter(this, void 0, void 0, function* () {
try {
// Remove the key from actual storage
yield storage.delete(storageKey);
// Remove the query from React Query cache
queryClient.removeQueries({ queryKey, exact: true });
}
catch (error) {
log(`❌ Failed to remove ${storageType} storage key: ${error}`, enableLogs || false, "error");
// Fall back to just removing the query from cache if storage fails
queryClient.removeQueries({ queryKey, exact: true });
}
});
}
/**
* Handles storage queries by detecting the storage type and delegating to the unified handler
* This function assumes the queryKey is already confirmed to be a storage query
* Expected format: ['#storage', 'storageType', 'key']
* Supported storage types: 'mmkv', 'asyncstorage', 'async-storage', 'async', 'securestorage', 'secure-storage', 'secure'
* Returns true if it was handled, false if it should fall back to regular query update
*/
export function handleStorageUpdate(queryKey, data, queryClient, storage, enableLogs, deviceName) {
const storageType = queryKey[1];
const storageKey = queryKey[2];
// Handle different storage types
switch (storageType.toLowerCase()) {
case "mmkv":
if (!storage) {
log(`⚠️ MMKV storage not configured for key: ${storageKey}`, enableLogs || false, "warn");
return false;
}
// Use unified handler for MMKV
handleStorageOperation(queryKey, data, queryClient, storageKey, storage, "MMKV", enableLogs, deviceName).catch((error) => {
log(`❌ MMKV storage update failed: ${error}`, enableLogs || false, "error");
// Fall back to regular query update if storage fails
queryClient.setQueryData(queryKey, data, {
updatedAt: Date.now(),
});
});
return true;
case "asyncstorage":
case "async-storage":
case "async":
if (!storage) {
log(`⚠️ AsyncStorage not configured for key: ${storageKey}`, enableLogs || false, "warn");
return false;
}
// Use unified handler for AsyncStorage
handleStorageOperation(queryKey, data, queryClient, storageKey, storage, "AsyncStorage", enableLogs, deviceName).catch((error) => {
log(`❌ AsyncStorage update failed: ${error}`, enableLogs || false, "error");
// Fall back to regular query update if storage fails
queryClient.setQueryData(queryKey, data, {
updatedAt: Date.now(),
});
});
return true;
case "securestorage":
case "secure-storage":
case "secure":
if (!storage) {
log(`⚠️ SecureStore not configured for key: ${storageKey}`, enableLogs || false, "warn");
return false;
}
// Use unified handler for SecureStore
handleStorageOperation(queryKey, data, queryClient, storageKey, storage, "SecureStore", enableLogs, deviceName).catch((error) => {
log(`❌ SecureStore update failed: ${error}`, enableLogs || false, "error");
// Fall back to regular query update if storage fails
queryClient.setQueryData(queryKey, data, {
updatedAt: Date.now(),
});
});
return true;
default:
// Unknown storage type, let the main function handle it as regular query
return false;
}
}
/**
* Handles storage query removal by detecting the storage type and delegating to the unified removal handler
* This function assumes the queryKey is already confirmed to be a storage query
* Expected format: ['#storage', 'storageType', 'key']
* Supported storage types: 'mmkv', 'asyncstorage', 'async-storage', 'async', 'securestorage', 'secure-storage', 'secure'
* Returns true if it was handled, false if it should fall back to regular query removal
*/
export function handleStorageRemoval(queryKey, queryClient, storage, enableLogs, deviceName) {
const storageType = queryKey[1];
const storageKey = queryKey[2];
// Handle different storage types
switch (storageType.toLowerCase()) {
case "mmkv":
if (!storage) {
log(`⚠️ MMKV storage not configured for key: ${storageKey}`, enableLogs || false, "warn");
return false;
}
// Use unified removal handler for MMKV
handleStorageRemovalOperation(queryKey, queryClient, storageKey, storage, "MMKV", enableLogs, deviceName).catch((error) => {
log(`❌ MMKV storage removal failed: ${error}`, enableLogs || false, "error");
// Fall back to regular query removal if storage fails
queryClient.removeQueries({ queryKey, exact: true });
});
return true;
case "asyncstorage":
case "async-storage":
case "async":
if (!storage) {
log(`⚠️ AsyncStorage not configured for key: ${storageKey}`, enableLogs || false, "warn");
return false;
}
// Use unified removal handler for AsyncStorage
handleStorageRemovalOperation(queryKey, queryClient, storageKey, storage, "AsyncStorage", enableLogs, deviceName).catch((error) => {
log(`❌ AsyncStorage removal failed: ${error}`, enableLogs || false, "error");
// Fall back to regular query removal if storage fails
queryClient.removeQueries({ queryKey, exact: true });
});
return true;
case "securestorage":
case "secure-storage":
case "secure":
if (!storage) {
log(`⚠️ SecureStore not configured for key: ${storageKey}`, enableLogs || false, "warn");
return false;
}
// Use unified removal handler for SecureStore
handleStorageRemovalOperation(queryKey, queryClient, storageKey, storage, "SecureStore", enableLogs, deviceName).catch((error) => {
log(`❌ SecureStore removal failed: ${error}`, enableLogs || false, "error");
// Fall back to regular query removal if storage fails
queryClient.removeQueries({ queryKey, exact: true });
});
return true;
default:
// Unknown storage type, let the main function handle it as regular query
return false;
}
}
//# sourceMappingURL=storageHandlers.js.map