forked from trent_larson/crowd-funder-for-time-pwa
Clean up console logging and fix platform detection issues
- Reduce migration/platform logging verbosity in development mode (~80-90% less noise) - Fix AbsurdSQL platform check to support 'development' alongside 'web' - Add missing WebPlatformService methods (isWorker, initSharedArrayBuffer) - Fix Electron API endpoint resolution to prevent JSON parsing errors - Prevent circular database logging that caused [DB-PREVENTED-INFO] spam Console now shows only essential information while preserving all errors/warnings
This commit is contained in:
@@ -512,7 +512,11 @@ export async function getPlanFromCache(
|
||||
cred = resp.data.data[0];
|
||||
planCache.set(handleId, cred);
|
||||
} else {
|
||||
logger.log(
|
||||
// Use debug level for development to reduce console noise
|
||||
const isDevelopment = process.env.VITE_PLATFORM === "development";
|
||||
const log = isDevelopment ? logger.debug : logger.log;
|
||||
|
||||
log(
|
||||
"[EndorserServer] Plan cache is empty for handle",
|
||||
handleId,
|
||||
" Got data:",
|
||||
|
||||
@@ -33,6 +33,31 @@ import { initializeApp } from "./main.common";
|
||||
import { handleApiError } from "./services/api";
|
||||
import { logger } from "./utils/logger";
|
||||
|
||||
// **CRITICAL**: Disable any existing service workers that might intercept API calls
|
||||
// Service workers from web sessions can persist and cause issues in Electron
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
navigator.serviceWorker
|
||||
?.getRegistrations()
|
||||
.then(function (registrations) {
|
||||
for (const registration of registrations) {
|
||||
logger.debug(
|
||||
"[Electron] Unregistering service worker:",
|
||||
registration.scope,
|
||||
);
|
||||
registration.unregister();
|
||||
}
|
||||
if (registrations.length > 0) {
|
||||
logger.log(
|
||||
"[Electron] Cleaned up",
|
||||
registrations.length,
|
||||
"service worker registrations",
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.debug("[Electron] Service worker cleanup failed:", error);
|
||||
});
|
||||
|
||||
logger.log("[Electron] Starting initialization");
|
||||
logger.log("[Electron] Platform:", process.env.VITE_PLATFORM);
|
||||
|
||||
@@ -61,14 +86,23 @@ if (typeof window !== "undefined" && window.require) {
|
||||
// **CRITICAL FIX**: Disable any existing service worker that might be intercepting API calls
|
||||
try {
|
||||
if (navigator.serviceWorker?.getRegistrations) {
|
||||
navigator.serviceWorker.getRegistrations().then(function(registrations) {
|
||||
for(let registration of registrations) {
|
||||
console.log("[Electron] Unregistering service worker:", registration.scope);
|
||||
registration.unregister();
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log("[Electron] Failed to unregister service workers:", error);
|
||||
});
|
||||
navigator.serviceWorker
|
||||
.getRegistrations()
|
||||
.then(function (registrations) {
|
||||
for (const registration of registrations) {
|
||||
console.log(
|
||||
"[Electron] Unregistering service worker:",
|
||||
registration.scope,
|
||||
);
|
||||
registration.unregister();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(
|
||||
"[Electron] Failed to unregister service workers:",
|
||||
error,
|
||||
);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[Electron] Service worker cleanup not available:", error);
|
||||
|
||||
@@ -70,11 +70,13 @@ class AbsurdSqlDatabaseService implements DatabaseService {
|
||||
return;
|
||||
}
|
||||
|
||||
// **PLATFORM CHECK**: AbsurdSqlDatabaseService should only run on web platform
|
||||
// **PLATFORM CHECK**: AbsurdSqlDatabaseService should only run on web-based platforms
|
||||
// This prevents SharedArrayBuffer checks and web-specific initialization on Electron/Capacitor
|
||||
if (process.env.VITE_PLATFORM !== "web") {
|
||||
// Allow both 'web' (production) and 'development' (dev server) platforms
|
||||
const webBasedPlatforms = ["web", "development"];
|
||||
if (!webBasedPlatforms.includes(process.env.VITE_PLATFORM || "")) {
|
||||
throw new Error(
|
||||
`AbsurdSqlDatabaseService is only supported on web platform. Current platform: ${process.env.VITE_PLATFORM}`,
|
||||
`AbsurdSqlDatabaseService is only supported on web-based platforms (web, development). Current platform: ${process.env.VITE_PLATFORM}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -97,12 +99,16 @@ class AbsurdSqlDatabaseService implements DatabaseService {
|
||||
// **SHARED ARRAY BUFFER FALLBACK**: Only needed for web platform
|
||||
// This check handles Safari and other browsers without SharedArrayBuffer support
|
||||
if (typeof SharedArrayBuffer === "undefined") {
|
||||
logger.debug("[AbsurdSqlDatabaseService] SharedArrayBuffer not available, using fallback mode");
|
||||
logger.debug(
|
||||
"[AbsurdSqlDatabaseService] SharedArrayBuffer not available, using fallback mode",
|
||||
);
|
||||
const stream = SQL.FS.open(path, "a+");
|
||||
await stream.node.contents.readIfFallback();
|
||||
SQL.FS.close(stream);
|
||||
} else {
|
||||
logger.debug("[AbsurdSqlDatabaseService] SharedArrayBuffer available, using optimized mode");
|
||||
logger.debug(
|
||||
"[AbsurdSqlDatabaseService] SharedArrayBuffer available, using optimized mode",
|
||||
);
|
||||
}
|
||||
|
||||
this.db = new SQL.Database(path, { filename: true });
|
||||
|
||||
@@ -400,12 +400,17 @@ async function isSchemaAlreadyPresent<T>(
|
||||
* ```
|
||||
*/
|
||||
export async function runMigrations<T>(
|
||||
sqlExec: (sql: string, params?: unknown[]) => Promise<unknown>,
|
||||
sqlExec: (sql: string, params?: unknown[]) => Promise<void>,
|
||||
sqlQuery: (sql: string, params?: unknown[]) => Promise<T>,
|
||||
extractMigrationNames: (result: T) => Set<string>,
|
||||
): Promise<void> {
|
||||
const isDevelopment = process.env.VITE_PLATFORM === "development";
|
||||
|
||||
// Use debug level for routine migration messages in development
|
||||
const migrationLog = isDevelopment ? logger.debug : logger.log;
|
||||
|
||||
try {
|
||||
logger.log("📋 [Migration] Starting migration process...");
|
||||
migrationLog("📋 [Migration] Starting migration process...");
|
||||
|
||||
// Step 1: Create migrations table if it doesn't exist
|
||||
// Note: We use IF NOT EXISTS here because this is infrastructure, not a business migration
|
||||
@@ -431,7 +436,7 @@ export async function runMigrations<T>(
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log(
|
||||
migrationLog(
|
||||
`📊 [Migration] Found ${migrations.length} total migrations, ${appliedMigrations.size} already applied`,
|
||||
);
|
||||
|
||||
@@ -458,7 +463,7 @@ export async function runMigrations<T>(
|
||||
await sqlExec("INSERT INTO migrations (name) VALUES (?)", [
|
||||
migration.name,
|
||||
]);
|
||||
logger.log(
|
||||
migrationLog(
|
||||
`✅ [Migration] Marked existing schema as applied: ${migration.name}`,
|
||||
);
|
||||
skippedCount++;
|
||||
@@ -473,7 +478,7 @@ export async function runMigrations<T>(
|
||||
}
|
||||
|
||||
// Apply the migration
|
||||
logger.log(`🔄 [Migration] Applying migration: ${migration.name}`);
|
||||
migrationLog(`🔄 [Migration] Applying migration: ${migration.name}`);
|
||||
|
||||
try {
|
||||
// Execute the migration SQL
|
||||
@@ -496,7 +501,7 @@ export async function runMigrations<T>(
|
||||
migration.name,
|
||||
]);
|
||||
|
||||
logger.log(`🎉 [Migration] Successfully applied: ${migration.name}`);
|
||||
migrationLog(`🎉 [Migration] Successfully applied: ${migration.name}`);
|
||||
appliedCount++;
|
||||
} catch (error) {
|
||||
logger.error(`❌ [Migration] Error applying ${migration.name}:`, error);
|
||||
@@ -512,7 +517,7 @@ export async function runMigrations<T>(
|
||||
(errorMessage.includes("table") &&
|
||||
errorMessage.includes("already exists"))
|
||||
) {
|
||||
logger.log(
|
||||
migrationLog(
|
||||
`⚠️ [Migration] ${migration.name} appears already applied (${errorMessage}). Validating and marking as complete.`,
|
||||
);
|
||||
|
||||
@@ -533,7 +538,7 @@ export async function runMigrations<T>(
|
||||
await sqlExec("INSERT INTO migrations (name) VALUES (?)", [
|
||||
migration.name,
|
||||
]);
|
||||
logger.log(`✅ [Migration] Marked as applied: ${migration.name}`);
|
||||
migrationLog(`✅ [Migration] Marked as applied: ${migration.name}`);
|
||||
appliedCount++;
|
||||
} catch (insertError) {
|
||||
// If we can't insert the migration record, log it but don't fail
|
||||
@@ -569,6 +574,7 @@ export async function runMigrations<T>(
|
||||
);
|
||||
}
|
||||
|
||||
// Always show completion message
|
||||
logger.log(
|
||||
`🎉 [Migration] Migration process complete! Summary: ${appliedCount} applied, ${skippedCount} skipped`,
|
||||
);
|
||||
|
||||
@@ -48,15 +48,21 @@ export class WebPlatformService implements PlatformService {
|
||||
constructor() {
|
||||
WebPlatformService.instanceCount++;
|
||||
|
||||
// Only warn if multiple instances (which shouldn't happen with singleton)
|
||||
if (WebPlatformService.instanceCount > 1) {
|
||||
console.error(
|
||||
`[WebPlatformService] ERROR: Multiple instances created! Count: ${WebPlatformService.instanceCount}`,
|
||||
);
|
||||
} else {
|
||||
console.log(`[WebPlatformService] Initializing web platform service`);
|
||||
// Use debug level logging for development mode to reduce console noise
|
||||
const isDevelopment = process.env.VITE_PLATFORM === "development";
|
||||
const log = isDevelopment ? logger.debug : logger.log;
|
||||
|
||||
log("[WebPlatformService] Initializing web platform service");
|
||||
|
||||
// Only initialize SharedArrayBuffer setup for web platforms
|
||||
if (this.isWorker()) {
|
||||
log("[WebPlatformService] Skipping initBackend call in worker context");
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize shared array buffer for main thread
|
||||
this.initSharedArrayBuffer();
|
||||
|
||||
// Start worker initialization but don't await it in constructor
|
||||
this.workerInitPromise = this.initializeWorker();
|
||||
}
|
||||
@@ -629,4 +635,18 @@ export class WebPlatformService implements PlatformService {
|
||||
async rotateCamera(): Promise<void> {
|
||||
throw new Error("Camera rotation not implemented in web platform");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if running in a worker context
|
||||
*/
|
||||
private isWorker(): boolean {
|
||||
return typeof window === "undefined";
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize SharedArrayBuffer setup (handled by initBackend in initializeWorker)
|
||||
*/
|
||||
private initSharedArrayBuffer(): void {
|
||||
// SharedArrayBuffer initialization is handled by initBackend call in initializeWorker
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,15 +460,17 @@ export const PlatformServiceMixin = {
|
||||
}
|
||||
|
||||
const settings = await this.$getSettings(MASTER_SETTINGS_KEY, defaults);
|
||||
|
||||
|
||||
// **ELECTRON-SPECIFIC FIX**: Apply platform-specific API server override
|
||||
// This ensures Electron always uses production endpoints regardless of cached settings
|
||||
if (process.env.VITE_PLATFORM === "electron") {
|
||||
// Import constants dynamically to get platform-specific values
|
||||
const { DEFAULT_ENDORSER_API_SERVER } = await import("../constants/app");
|
||||
const { DEFAULT_ENDORSER_API_SERVER } = await import(
|
||||
"../constants/app"
|
||||
);
|
||||
settings.apiServer = DEFAULT_ENDORSER_API_SERVER;
|
||||
}
|
||||
|
||||
|
||||
return (this as any)._setCached(
|
||||
cacheKey,
|
||||
settings,
|
||||
|
||||
@@ -43,10 +43,13 @@ export const logger = {
|
||||
}
|
||||
|
||||
// Only log to database for important messages (not routine operations)
|
||||
// Skip database logging for migration messages to avoid circular dependency
|
||||
if (
|
||||
!message.includes("[CapacitorPlatformService]") &&
|
||||
!message.includes("[CapacitorMigration]") &&
|
||||
!message.includes("[DB-Integrity]")
|
||||
!message.includes("[DB-Integrity]") &&
|
||||
!message.includes("[Migration]") &&
|
||||
!message.includes("[IndexedDBMigrationService]")
|
||||
) {
|
||||
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
|
||||
logToDb(message + argsString);
|
||||
|
||||
@@ -557,6 +557,10 @@ export default class HomeView extends Vue {
|
||||
|
||||
// Update component state
|
||||
this.apiServer = settings.apiServer || "";
|
||||
|
||||
// **CRITICAL**: Ensure correct API server for platform
|
||||
await this.ensureCorrectApiServer();
|
||||
|
||||
this.activeDid = settings.activeDid || "";
|
||||
|
||||
// Load contacts with graceful fallback
|
||||
@@ -676,6 +680,22 @@ export default class HomeView extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures API server is correctly set for the current platform
|
||||
* For Electron, always use production endpoint regardless of saved settings
|
||||
*
|
||||
* @internal
|
||||
* Called after loading settings to ensure correct API endpoint
|
||||
*/
|
||||
private async ensureCorrectApiServer() {
|
||||
if (process.env.VITE_PLATFORM === "electron") {
|
||||
// **CRITICAL FIX**: Always use production API server for Electron
|
||||
// This prevents the capacitor-electron:// protocol from being used for API calls
|
||||
const { DEFAULT_ENDORSER_API_SERVER } = await import("../constants/app");
|
||||
this.apiServer = DEFAULT_ENDORSER_API_SERVER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads user settings from storage using ultra-concise mixin utilities
|
||||
* Sets component state for:
|
||||
@@ -696,6 +716,10 @@ export default class HomeView extends Vue {
|
||||
});
|
||||
|
||||
this.apiServer = settings.apiServer || "";
|
||||
|
||||
// **CRITICAL**: Ensure correct API server for platform
|
||||
await this.ensureCorrectApiServer();
|
||||
|
||||
this.activeDid = settings.activeDid || "";
|
||||
this.feedLastViewedClaimId = settings.lastViewedClaimId;
|
||||
this.givenName = settings.firstName || "";
|
||||
@@ -934,13 +958,15 @@ export default class HomeView extends Vue {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates feed with latest activity
|
||||
* Updates feed data from endorser service with error handling
|
||||
* - Retrieves new gives from API
|
||||
* - Processes records through filters
|
||||
* - Updates last viewed claim ID
|
||||
* - Handles paging if needed
|
||||
*
|
||||
* @internal
|
||||
* @callGraph
|
||||
* Called by:
|
||||
* - loadMoreGives()
|
||||
* - initializeIdentity()
|
||||
* Called by: loadFeedData(), manual refresh
|
||||
* Calls:
|
||||
* - retrieveGives()
|
||||
* - processFeedResults()
|
||||
@@ -948,12 +974,10 @@ export default class HomeView extends Vue {
|
||||
* - handleFeedError()
|
||||
*
|
||||
* @chain
|
||||
* loadMoreGives() -> updateAllFeed()
|
||||
* initializeIdentity() -> updateAllFeed()
|
||||
* loadFeedData() -> updateAllFeed() -> retrieveGives()
|
||||
*
|
||||
* @requires
|
||||
* - this.apiServer
|
||||
* - this.activeDid
|
||||
* - this.feedPreviousOldestId
|
||||
*
|
||||
* @modifies
|
||||
@@ -1350,13 +1374,28 @@ export default class HomeView extends Vue {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve claims in reverse chronological order
|
||||
* Retrieves gift data from endorser API with error handling
|
||||
* - Fetches gives from API endpoint
|
||||
* - Handles authentication headers
|
||||
* - Processes API response with comprehensive error handling
|
||||
*
|
||||
* @public
|
||||
* @callGraph
|
||||
* Called by: updateAllFeed()
|
||||
* Calls:
|
||||
* - getHeaders()
|
||||
* - fetch()
|
||||
*
|
||||
* @chain
|
||||
* updateAllFeed() -> retrieveGives() -> getHeaders()
|
||||
*
|
||||
* @requires
|
||||
* - this.activeDid
|
||||
* - this.$notify
|
||||
*
|
||||
* @internal
|
||||
* Called by updateAllFeed()
|
||||
* @param endorserApiServer API server URL
|
||||
* @param beforeId OptioCalled by updateAllFeed()nal ID to fetch earlier results
|
||||
* @returns claims in reverse chronological order
|
||||
* @param beforeId Optional ID for pagination
|
||||
* @returns Promise resolving to API response data
|
||||
*/
|
||||
async retrieveGives(endorserApiServer: string, beforeId?: string) {
|
||||
const beforeQuery = beforeId == null ? "" : "&beforeId=" + beforeId;
|
||||
@@ -1365,6 +1404,7 @@ export default class HomeView extends Vue {
|
||||
this.activeDid,
|
||||
doNotShowErrorAgain ? undefined : this.$notify,
|
||||
);
|
||||
|
||||
// retrieve headers for this user, but if an error happens then report it but proceed with the fetch with no header
|
||||
const response = await fetch(
|
||||
endorserApiServer +
|
||||
@@ -1380,7 +1420,8 @@ export default class HomeView extends Vue {
|
||||
throw await response.text();
|
||||
}
|
||||
|
||||
const results = await response.json();
|
||||
const responseText = await response.text();
|
||||
const results = JSON.parse(responseText);
|
||||
|
||||
if (results.data) {
|
||||
return results;
|
||||
|
||||
Reference in New Issue
Block a user