@ -187,8 +187,11 @@ export class CapacitorPlatformService implements PlatformService {
params : unknown [ ] = [ ] ,
params : unknown [ ] = [ ] ,
) : Promise < R > {
) : Promise < R > {
// Log incoming parameters for debugging (HIGH PRIORITY)
// Log incoming parameters for debugging (HIGH PRIORITY)
logger . warn ( ` [CapacitorPlatformService] queueOperation - SQL: ${ sql } , Params: ` , params ) ;
logger . warn (
` [CapacitorPlatformService] queueOperation - SQL: ${ sql } , Params: ` ,
params ,
) ;
// Convert parameters to SQLite-compatible types with robust serialization
// Convert parameters to SQLite-compatible types with robust serialization
const convertedParams = params . map ( ( param , index ) = > {
const convertedParams = params . map ( ( param , index ) = > {
if ( param === null || param === undefined ) {
if ( param === null || param === undefined ) {
@ -196,51 +199,75 @@ export class CapacitorPlatformService implements PlatformService {
}
}
if ( typeof param === "object" && param !== null ) {
if ( typeof param === "object" && param !== null ) {
// Enhanced debug logging for all objects (HIGH PRIORITY)
// Enhanced debug logging for all objects (HIGH PRIORITY)
logger . warn ( ` [CapacitorPlatformService] Object param at index ${ index } : ` , {
logger . warn (
type : typeof param ,
` [CapacitorPlatformService] Object param at index ${ index } : ` ,
toString : param.toString ( ) ,
{
constructorName : param.constructor?.name ,
type : typeof param ,
isArray : Array.isArray ( param ) ,
toString : param.toString ( ) ,
keys : Object.keys ( param ) ,
constructorName : param.constructor?.name ,
stringRep : String ( param )
isArray : Array.isArray ( param ) ,
} ) ;
keys : Object.keys ( param ) ,
stringRep : String ( param ) ,
} ,
) ;
// Special handling for Proxy objects (common cause of "An object could not be cloned")
// Special handling for Proxy objects (common cause of "An object could not be cloned")
const isProxy = this . isProxyObject ( param ) ;
const isProxy = this . isProxyObject ( param ) ;
logger . warn ( ` [CapacitorPlatformService] isProxy result for index ${ index } : ` , isProxy ) ;
logger . warn (
` [CapacitorPlatformService] isProxy result for index ${ index } : ` ,
isProxy ,
) ;
// AGGRESSIVE: If toString contains "Proxy", treat as Proxy even if isProxyObject returns false
// AGGRESSIVE: If toString contains "Proxy", treat as Proxy even if isProxyObject returns false
const stringRep = String ( param ) ;
const stringRep = String ( param ) ;
const forceProxyDetection = stringRep . includes ( 'Proxy(' ) || stringRep . startsWith ( 'Proxy' ) ;
const forceProxyDetection =
logger . warn ( ` [CapacitorPlatformService] Force proxy detection for index ${ index } : ` , forceProxyDetection ) ;
stringRep . includes ( "Proxy(" ) || stringRep . startsWith ( "Proxy" ) ;
logger . warn (
` [CapacitorPlatformService] Force proxy detection for index ${ index } : ` ,
forceProxyDetection ,
) ;
if ( isProxy || forceProxyDetection ) {
if ( isProxy || forceProxyDetection ) {
logger . warn ( ` [CapacitorPlatformService] Proxy object detected at index ${ index } (method: ${ isProxy ? 'isProxyObject' : 'stringDetection' } ), toString: ${ stringRep } ` ) ;
logger . warn (
` [CapacitorPlatformService] Proxy object detected at index ${ index } (method: ${ isProxy ? "isProxyObject" : "stringDetection" } ), toString: ${ stringRep } ` ,
) ;
try {
try {
// AGGRESSIVE EXTRACTION: Try multiple methods to extract actual values
// AGGRESSIVE EXTRACTION: Try multiple methods to extract actual values
if ( Array . isArray ( param ) ) {
if ( Array . isArray ( param ) ) {
// Method 1: Array.from() to extract from Proxy(Array)
// Method 1: Array.from() to extract from Proxy(Array)
const actualArray = Array . from ( param ) ;
const actualArray = Array . from ( param ) ;
logger . info ( ` [CapacitorPlatformService] Extracted array from Proxy via Array.from(): ` , actualArray ) ;
logger . info (
` [CapacitorPlatformService] Extracted array from Proxy via Array.from(): ` ,
actualArray ,
) ;
// Method 2: Manual element extraction for safety
// Method 2: Manual element extraction for safety
const manualArray : unknown [ ] = [ ] ;
const manualArray : unknown [ ] = [ ] ;
for ( let i = 0 ; i < param . length ; i ++ ) {
for ( let i = 0 ; i < param . length ; i ++ ) {
manualArray . push ( param [ i ] ) ;
manualArray . push ( param [ i ] ) ;
}
}
logger . info ( ` [CapacitorPlatformService] Manual array extraction: ` , manualArray ) ;
logger . info (
` [CapacitorPlatformService] Manual array extraction: ` ,
manualArray ,
) ;
// Use the manual extraction as it's more reliable
// Use the manual extraction as it's more reliable
return manualArray ;
return manualArray ;
} else {
} else {
// For Proxy(Object), try to extract actual object
// For Proxy(Object), try to extract actual object
const actualObject = Object . assign ( { } , param ) ;
const actualObject = Object . assign ( { } , param ) ;
logger . info ( ` [CapacitorPlatformService] Extracted object from Proxy: ` , actualObject ) ;
logger . info (
` [CapacitorPlatformService] Extracted object from Proxy: ` ,
actualObject ,
) ;
return actualObject ;
return actualObject ;
}
}
} catch ( proxyError ) {
} catch ( proxyError ) {
logger . error ( ` [CapacitorPlatformService] Failed to extract from Proxy at index ${ index } : ` , proxyError ) ;
logger . error (
` [CapacitorPlatformService] Failed to extract from Proxy at index ${ index } : ` ,
proxyError ,
) ;
// FALLBACK: Try to extract primitive values manually
// FALLBACK: Try to extract primitive values manually
if ( Array . isArray ( param ) ) {
if ( Array . isArray ( param ) ) {
try {
try {
@ -248,30 +275,42 @@ export class CapacitorPlatformService implements PlatformService {
for ( let i = 0 ; i < param . length ; i ++ ) {
for ( let i = 0 ; i < param . length ; i ++ ) {
fallbackArray . push ( param [ i ] ) ;
fallbackArray . push ( param [ i ] ) ;
}
}
logger . info ( ` [CapacitorPlatformService] Fallback array extraction successful: ` , fallbackArray ) ;
logger . info (
` [CapacitorPlatformService] Fallback array extraction successful: ` ,
fallbackArray ,
) ;
return fallbackArray ;
return fallbackArray ;
} catch ( fallbackError ) {
} catch ( fallbackError ) {
logger . error ( ` [CapacitorPlatformService] Fallback array extraction failed: ` , fallbackError ) ;
logger . error (
` [CapacitorPlatformService] Fallback array extraction failed: ` ,
fallbackError ,
) ;
return ` [Proxy Array - Could not extract] ` ;
return ` [Proxy Array - Could not extract] ` ;
}
}
}
}
return ` [Proxy Object - Could not extract] ` ;
return ` [Proxy Object - Could not extract] ` ;
}
}
}
}
try {
try {
// Safely convert objects and arrays to JSON strings
// Safely convert objects and arrays to JSON strings
return JSON . stringify ( param ) ;
return JSON . stringify ( param ) ;
} catch ( error ) {
} catch ( error ) {
// Handle non-serializable objects
// Handle non-serializable objects
logger . error ( ` [CapacitorPlatformService] Failed to serialize parameter at index ${ index } : ` , error ) ;
logger . error (
logger . error ( ` [CapacitorPlatformService] Problematic parameter: ` , param ) ;
` [CapacitorPlatformService] Failed to serialize parameter at index ${ index } : ` ,
error ,
) ;
logger . error (
` [CapacitorPlatformService] Problematic parameter: ` ,
param ,
) ;
// Fallback: Convert to string representation
// Fallback: Convert to string representation
if ( Array . isArray ( param ) ) {
if ( Array . isArray ( param ) ) {
return ` [Array( ${ param . length } )] ` ;
return ` [Array( ${ param . length } )] ` ;
}
}
return ` [Object ${ param . constructor ? . name || 'Unknown' } ] ` ;
return ` [Object ${ param . constructor ? . name || "Unknown" } ] ` ;
}
}
}
}
if ( typeof param === "boolean" ) {
if ( typeof param === "boolean" ) {
@ -280,12 +319,16 @@ export class CapacitorPlatformService implements PlatformService {
}
}
if ( typeof param === "function" ) {
if ( typeof param === "function" ) {
// Functions can't be serialized - convert to string representation
// Functions can't be serialized - convert to string representation
logger . warn ( ` [CapacitorPlatformService] Function parameter detected and converted to string at index ${ index } ` ) ;
logger . warn (
return ` [Function ${ param . name || 'Anonymous' } ] ` ;
` [CapacitorPlatformService] Function parameter detected and converted to string at index ${ index } ` ,
) ;
return ` [Function ${ param . name || "Anonymous" } ] ` ;
}
}
if ( typeof param === "symbol" ) {
if ( typeof param === "symbol" ) {
// Symbols can't be serialized - convert to string representation
// Symbols can't be serialized - convert to string representation
logger . warn ( ` [CapacitorPlatformService] Symbol parameter detected and converted to string at index ${ index } ` ) ;
logger . warn (
` [CapacitorPlatformService] Symbol parameter detected and converted to string at index ${ index } ` ,
) ;
return param . toString ( ) ;
return param . toString ( ) ;
}
}
// Numbers, strings, bigints are supported, but ensure bigints are converted to strings
// Numbers, strings, bigints are supported, but ensure bigints are converted to strings
@ -296,13 +339,16 @@ export class CapacitorPlatformService implements PlatformService {
} ) ;
} ) ;
// Log converted parameters for debugging (HIGH PRIORITY)
// Log converted parameters for debugging (HIGH PRIORITY)
logger . warn ( ` [CapacitorPlatformService] Converted params: ` , convertedParams ) ;
logger . warn (
` [CapacitorPlatformService] Converted params: ` ,
convertedParams ,
) ;
return new Promise < R > ( ( resolve , reject ) = > {
return new Promise < R > ( ( resolve , reject ) = > {
// Create completely plain objects that Vue cannot make reactive
// Create completely plain objects that Vue cannot make reactive
// Step 1: Deep clone the converted params to ensure they're plain objects
// Step 1: Deep clone the converted params to ensure they're plain objects
const plainParams = JSON . parse ( JSON . stringify ( convertedParams ) ) ;
const plainParams = JSON . parse ( JSON . stringify ( convertedParams ) ) ;
// Step 2: Create operation object using Object.create(null) for no prototype
// Step 2: Create operation object using Object.create(null) for no prototype
const operation = Object . create ( null ) as QueuedOperation ;
const operation = Object . create ( null ) as QueuedOperation ;
operation . type = type ;
operation . type = type ;
@ -310,16 +356,25 @@ export class CapacitorPlatformService implements PlatformService {
operation . params = plainParams ;
operation . params = plainParams ;
operation . resolve = ( value : unknown ) = > resolve ( value as R ) ;
operation . resolve = ( value : unknown ) = > resolve ( value as R ) ;
operation . reject = reject ;
operation . reject = reject ;
// Step 3: Freeze everything to prevent modification
// Step 3: Freeze everything to prevent modification
Object . freeze ( operation . params ) ;
Object . freeze ( operation . params ) ;
Object . freeze ( operation ) ;
Object . freeze ( operation ) ;
// Add enhanced logging to verify our fix
// Add enhanced logging to verify our fix
logger . warn ( ` [CapacitorPlatformService] Final operation.params type: ` , typeof operation . params ) ;
logger . warn (
logger . warn ( ` [CapacitorPlatformService] Final operation.params toString: ` , operation . params . toString ( ) ) ;
` [CapacitorPlatformService] Final operation.params type: ` ,
logger . warn ( ` [CapacitorPlatformService] Final operation.params constructor: ` , operation . params . constructor ? . name ) ;
typeof operation . params ,
) ;
logger . warn (
` [CapacitorPlatformService] Final operation.params toString: ` ,
operation . params . toString ( ) ,
) ;
logger . warn (
` [CapacitorPlatformService] Final operation.params constructor: ` ,
operation . params . constructor ? . name ,
) ;
this . operationQueue . push ( operation ) ;
this . operationQueue . push ( operation ) ;
// If we're already initialized, start processing the queue
// If we're already initialized, start processing the queue
@ -367,33 +422,42 @@ export class CapacitorPlatformService implements PlatformService {
try {
try {
// Method 1: Check toString representation
// Method 1: Check toString representation
const objString = obj . toString ( ) ;
const objString = obj . toString ( ) ;
if ( objString . includes ( 'Proxy(' ) || objString . startsWith ( 'Proxy' ) ) {
if ( objString . includes ( "Proxy(" ) || objString . startsWith ( "Proxy" ) ) {
logger . debug ( "[CapacitorPlatformService] Proxy detected via toString:" , objString ) ;
logger . debug (
"[CapacitorPlatformService] Proxy detected via toString:" ,
objString ,
) ;
return true ;
return true ;
}
}
// Method 2: Check constructor name
// Method 2: Check constructor name
const constructorName = obj . constructor ? . name ;
const constructorName = obj . constructor ? . name ;
if ( constructorName === 'Proxy' ) {
if ( constructorName === "Proxy" ) {
logger . debug ( "[CapacitorPlatformService] Proxy detected via constructor name" ) ;
logger . debug (
"[CapacitorPlatformService] Proxy detected via constructor name" ,
) ;
return true ;
return true ;
}
}
// Method 3: Check Object.prototype.toString
// Method 3: Check Object.prototype.toString
const objToString = Object . prototype . toString . call ( obj ) ;
const objToString = Object . prototype . toString . call ( obj ) ;
if ( objToString . includes ( 'Proxy' ) ) {
if ( objToString . includes ( "Proxy" ) ) {
logger . debug ( "[CapacitorPlatformService] Proxy detected via Object.prototype.toString" ) ;
logger . debug (
"[CapacitorPlatformService] Proxy detected via Object.prototype.toString" ,
) ;
return true ;
return true ;
}
}
// Method 4: Vue/Reactive Proxy detection - check for __v_ properties
// Method 4: Vue/Reactive Proxy detection - check for __v_ properties
if ( typeof obj === 'object' && obj !== null ) {
if ( typeof obj === "object" && obj !== null ) {
// Check for Vue reactive proxy indicators
// Check for Vue reactive proxy indicators
const hasVueProxy = Object . getOwnPropertyNames ( obj ) . some ( prop = >
const hasVueProxy = Object . getOwnPropertyNames ( obj ) . some (
prop . startsWith ( '__v_' ) || prop . startsWith ( '__r_' )
( prop ) = > prop . startsWith ( "__v_" ) || prop . startsWith ( "__r_" ) ,
) ;
) ;
if ( hasVueProxy ) {
if ( hasVueProxy ) {
logger . debug ( "[CapacitorPlatformService] Vue reactive Proxy detected" ) ;
logger . debug (
"[CapacitorPlatformService] Vue reactive Proxy detected" ,
) ;
return true ;
return true ;
}
}
}
}
@ -401,15 +465,24 @@ export class CapacitorPlatformService implements PlatformService {
// Method 5: Try JSON.stringify and check for Proxy in error or result
// Method 5: Try JSON.stringify and check for Proxy in error or result
try {
try {
const jsonString = JSON . stringify ( obj ) ;
const jsonString = JSON . stringify ( obj ) ;
if ( jsonString . includes ( 'Proxy' ) ) {
if ( jsonString . includes ( "Proxy" ) ) {
logger . debug ( "[CapacitorPlatformService] Proxy detected in JSON serialization" ) ;
logger . debug (
"[CapacitorPlatformService] Proxy detected in JSON serialization" ,
) ;
return true ;
return true ;
}
}
} catch ( jsonError ) {
} catch ( jsonError ) {
// If JSON.stringify fails, it might be a non-serializable Proxy
// If JSON.stringify fails, it might be a non-serializable Proxy
const errorMessage = jsonError instanceof Error ? jsonError.message : String ( jsonError ) ;
const errorMessage =
if ( errorMessage . includes ( 'Proxy' ) || errorMessage . includes ( 'circular' ) || errorMessage . includes ( 'clone' ) ) {
jsonError instanceof Error ? jsonError.message : String ( jsonError ) ;
logger . debug ( "[CapacitorPlatformService] Proxy detected via JSON serialization error" ) ;
if (
errorMessage . includes ( "Proxy" ) ||
errorMessage . includes ( "circular" ) ||
errorMessage . includes ( "clone" )
) {
logger . debug (
"[CapacitorPlatformService] Proxy detected via JSON serialization error" ,
) ;
return true ;
return true ;
}
}
}
}
@ -417,7 +490,10 @@ export class CapacitorPlatformService implements PlatformService {
return false ;
return false ;
} catch ( error ) {
} catch ( error ) {
// If we can't inspect the object, it might be a Proxy causing issues
// If we can't inspect the object, it might be a Proxy causing issues
logger . warn ( "[CapacitorPlatformService] Could not inspect object for Proxy detection:" , error ) ;
logger . warn (
"[CapacitorPlatformService] Could not inspect object for Proxy detection:" ,
error ,
) ;
return true ; // Assume it's a Proxy if we can't inspect it
return true ; // Assume it's a Proxy if we can't inspect it
}
}
}
}
@ -1268,8 +1344,12 @@ export class CapacitorPlatformService implements PlatformService {
params? : unknown [ ] ,
params? : unknown [ ] ,
) : Promise < unknown [ ] | undefined > {
) : Promise < unknown [ ] | undefined > {
await this . waitForInitialization ( ) ;
await this . waitForInitialization ( ) ;
const result = await this . queueOperation < QueryExecResult > ( "query" , sql , params || [ ] ) ;
const result = await this . queueOperation < QueryExecResult > (
"query" ,
sql ,
params || [ ] ,
) ;
// Return the first row from the result, or undefined if no results
// Return the first row from the result, or undefined if no results
if ( result && result . values && result . values . length > 0 ) {
if ( result && result . values && result . values . length > 0 ) {
return result . values [ 0 ] ;
return result . values [ 0 ] ;