mirror of
https://github.com/colanode/colanode.git
synced 2025-12-29 00:25:03 +01:00
Refactor debuggers
This commit is contained in:
@@ -21,9 +21,9 @@ import { eventBus } from '@/shared/lib/event-bus';
|
||||
import { QueryInput, QueryMap } from '@/shared/queries';
|
||||
import { Event } from '@/shared/types/events';
|
||||
|
||||
class Mediator {
|
||||
private readonly debug = createDebugger('desktop:mediator');
|
||||
const debug = createDebugger('desktop:mediator');
|
||||
|
||||
class Mediator {
|
||||
private readonly subscribedQueries: Map<string, SubscribedQuery<QueryInput>> =
|
||||
new Map();
|
||||
|
||||
@@ -44,7 +44,7 @@ class Mediator {
|
||||
public async executeQuery<T extends QueryInput>(
|
||||
input: T
|
||||
): Promise<QueryMap[T['type']]['output']> {
|
||||
this.debug(`Executing query: ${input.type}`);
|
||||
debug(`Executing query: ${input.type}`);
|
||||
|
||||
const handler = queryHandlerMap[input.type] as unknown as QueryHandler<T>;
|
||||
|
||||
@@ -60,7 +60,7 @@ class Mediator {
|
||||
id: string,
|
||||
input: T
|
||||
): Promise<QueryMap[T['type']]['output']> {
|
||||
this.debug(`Executing query and subscribing: ${input.type}`);
|
||||
debug(`Executing query and subscribing: ${input.type}`);
|
||||
|
||||
if (this.subscribedQueries.has(id)) {
|
||||
return this.subscribedQueries.get(id)!.result;
|
||||
@@ -80,7 +80,7 @@ class Mediator {
|
||||
}
|
||||
|
||||
public unsubscribeQuery(id: string) {
|
||||
this.debug(`Unsubscribing query: ${id}`);
|
||||
debug(`Unsubscribing query: ${id}`);
|
||||
this.subscribedQueries.delete(id);
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ class Mediator {
|
||||
input.type
|
||||
] as unknown as MutationHandler<T>;
|
||||
|
||||
this.debug(`Executing mutation: ${input.type}`);
|
||||
debug(`Executing mutation: ${input.type}`);
|
||||
|
||||
try {
|
||||
if (!handler) {
|
||||
@@ -160,7 +160,7 @@ class Mediator {
|
||||
const output = await handler.handleMutation(input);
|
||||
return { success: true, output };
|
||||
} catch (error) {
|
||||
this.debug(`Error executing mutation: ${input.type}`, error);
|
||||
debug(`Error executing mutation: ${input.type}`, error);
|
||||
if (error instanceof MutationError) {
|
||||
return {
|
||||
success: false,
|
||||
@@ -184,7 +184,7 @@ class Mediator {
|
||||
public async executeCommand<T extends CommandInput>(
|
||||
input: T
|
||||
): Promise<CommandMap[T['type']]['output']> {
|
||||
this.debug(`Executing command: ${input.type}`);
|
||||
debug(`Executing command: ${input.type}`);
|
||||
|
||||
const handler = commandHandlerMap[
|
||||
input.type
|
||||
|
||||
@@ -10,8 +10,9 @@ import { createDebugger } from '@colanode/core';
|
||||
import { AccountService } from '@/main/services/accounts/account-service';
|
||||
import { BackoffCalculator } from '@/main/lib/backoff-calculator';
|
||||
|
||||
const debug = createDebugger('desktop:service:account');
|
||||
|
||||
export class AccountClient {
|
||||
private readonly debug = createDebugger('desktop:service:account');
|
||||
private readonly backoff: BackoffCalculator = new BackoffCalculator();
|
||||
private readonly axiosInstance: AxiosInstance;
|
||||
private readonly account: AccountService;
|
||||
@@ -33,7 +34,7 @@ export class AccountClient {
|
||||
}
|
||||
|
||||
try {
|
||||
this.debug(`Requesting ${method} ${path} for account ${this.account.id}`);
|
||||
debug(`Requesting ${method} ${path} for account ${this.account.id}`);
|
||||
|
||||
const headers = {
|
||||
...config.headers,
|
||||
@@ -50,7 +51,7 @@ export class AccountClient {
|
||||
this.backoff.reset();
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.debug(`Error in request for account ${this.account.id}: ${error}`);
|
||||
debug(`Error in request for account ${this.account.id}: ${error}`);
|
||||
if (isAxiosError(error) && this.shouldBackoff(error)) {
|
||||
this.backoff.increaseError();
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ import { AccountService } from '@/main/services/accounts/account-service';
|
||||
import { EventLoop } from '@/main/lib/event-loop';
|
||||
import { eventBus } from '@/shared/lib/event-bus';
|
||||
|
||||
const debug = createDebugger('desktop:service:account-connection');
|
||||
|
||||
export class AccountConnection {
|
||||
private readonly debug = createDebugger('service:account-connection');
|
||||
private readonly account: AccountService;
|
||||
private readonly eventLoop: EventLoop;
|
||||
|
||||
@@ -45,7 +46,7 @@ export class AccountConnection {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(`Initializing socket connection for account ${this.account.id}`);
|
||||
debug(`Initializing socket connection for account ${this.account.id}`);
|
||||
|
||||
if (this.socket && this.isConnected()) {
|
||||
this.socket.ping();
|
||||
@@ -66,7 +67,7 @@ export class AccountConnection {
|
||||
const data: string = event.data.toString();
|
||||
const message: Message = JSON.parse(data);
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Received message of type ${message.type} for account ${this.account.id}`
|
||||
);
|
||||
|
||||
@@ -78,7 +79,7 @@ export class AccountConnection {
|
||||
};
|
||||
|
||||
this.socket.onopen = () => {
|
||||
this.debug(`Socket connection for account ${this.account.id} opened`);
|
||||
debug(`Socket connection for account ${this.account.id} opened`);
|
||||
|
||||
this.backoffCalculator.reset();
|
||||
eventBus.publish({
|
||||
@@ -88,7 +89,7 @@ export class AccountConnection {
|
||||
};
|
||||
|
||||
this.socket.onerror = () => {
|
||||
this.debug(`Socket connection for account ${this.account.id} errored`);
|
||||
debug(`Socket connection for account ${this.account.id} errored`);
|
||||
this.backoffCalculator.increaseError();
|
||||
eventBus.publish({
|
||||
type: 'account_connection_closed',
|
||||
@@ -97,7 +98,7 @@ export class AccountConnection {
|
||||
};
|
||||
|
||||
this.socket.onclose = () => {
|
||||
this.debug(`Socket connection for account ${this.account.id} closed`);
|
||||
debug(`Socket connection for account ${this.account.id} closed`);
|
||||
this.backoffCalculator.increaseError();
|
||||
eventBus.publish({
|
||||
type: 'account_connection_closed',
|
||||
@@ -112,7 +113,7 @@ export class AccountConnection {
|
||||
|
||||
public send(message: Message): boolean {
|
||||
if (this.socket && this.isConnected()) {
|
||||
this.debug(
|
||||
debug(
|
||||
`Sending message of type ${message.type} for account ${this.account.id}`
|
||||
);
|
||||
|
||||
@@ -125,7 +126,7 @@ export class AccountConnection {
|
||||
|
||||
public close(): void {
|
||||
if (this.socket) {
|
||||
this.debug(`Closing socket connection for account ${this.account.id}`);
|
||||
debug(`Closing socket connection for account ${this.account.id}`);
|
||||
this.socket.close();
|
||||
this.socket = null;
|
||||
}
|
||||
@@ -135,7 +136,7 @@ export class AccountConnection {
|
||||
}
|
||||
|
||||
private checkConnection(): void {
|
||||
this.debug(`Checking connection for account ${this.account.id}`);
|
||||
debug(`Checking connection for account ${this.account.id}`);
|
||||
if (!this.account.server.isAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,9 @@ import { Account } from '@/shared/types/accounts';
|
||||
import { Workspace } from '@/shared/types/workspaces';
|
||||
import { EventLoop } from '@/main/lib/event-loop';
|
||||
|
||||
const debug = createDebugger('desktop:service:account');
|
||||
|
||||
export class AccountService {
|
||||
private readonly debug = createDebugger('desktop:service:account');
|
||||
private readonly workspaces: Map<string, WorkspaceService> = new Map();
|
||||
private readonly eventLoop: EventLoop;
|
||||
private readonly account: Account;
|
||||
@@ -44,7 +45,7 @@ export class AccountService {
|
||||
private readonly eventSubscriptionId: string;
|
||||
|
||||
constructor(account: Account, server: ServerService, app: AppService) {
|
||||
this.debug(`Initializing account service for account ${account.id}`);
|
||||
debug(`Initializing account service for account ${account.id}`);
|
||||
|
||||
this.account = account;
|
||||
this.server = server;
|
||||
@@ -171,12 +172,12 @@ export class AccountService {
|
||||
account: this.account,
|
||||
});
|
||||
} catch (error) {
|
||||
this.debug(`Error logging out of account ${this.account.id}: ${error}`);
|
||||
debug(`Error logging out of account ${this.account.id}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
private async migrate(): Promise<void> {
|
||||
this.debug(`Migrating account database for account ${this.account.id}`);
|
||||
debug(`Migrating account database for account ${this.account.id}`);
|
||||
const migrator = new Migrator({
|
||||
db: this.database,
|
||||
provider: {
|
||||
@@ -234,10 +235,10 @@ export class AccountService {
|
||||
}
|
||||
|
||||
private async sync(): Promise<void> {
|
||||
this.debug(`Syncing account ${this.account.id}`);
|
||||
debug(`Syncing account ${this.account.id}`);
|
||||
|
||||
if (!this.server.isAvailable) {
|
||||
this.debug(
|
||||
debug(
|
||||
`Server ${this.server.domain} is not available for syncing account ${this.account.email}`
|
||||
);
|
||||
return;
|
||||
@@ -271,12 +272,11 @@ export class AccountService {
|
||||
.executeTakeFirst();
|
||||
|
||||
if (!updatedAccount) {
|
||||
this.debug(`Failed to update account ${this.account.email} after sync`);
|
||||
debug(`Failed to update account ${this.account.email} after sync`);
|
||||
return;
|
||||
} else {
|
||||
this.debug(`Updated account ${this.account.email} after sync`);
|
||||
}
|
||||
|
||||
debug(`Updated account ${this.account.email} after sync`);
|
||||
const account = mapAccount(updatedAccount);
|
||||
this.updateAccount(account);
|
||||
|
||||
@@ -306,7 +306,7 @@ export class AccountService {
|
||||
.executeTakeFirst();
|
||||
|
||||
if (!createdWorkspace) {
|
||||
this.debug(`Failed to create workspace ${workspace.id}`);
|
||||
debug(`Failed to create workspace ${workspace.id}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -357,14 +357,12 @@ export class AccountService {
|
||||
} catch (error) {
|
||||
const parsedError = parseApiError(error);
|
||||
if (this.isSyncInvalid(parsedError)) {
|
||||
this.debug(
|
||||
`Account ${this.account.email} is not valid, logging out...`
|
||||
);
|
||||
debug(`Account ${this.account.email} is not valid, logging out...`);
|
||||
await this.logout();
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(`Failed to sync account ${this.account.email}: ${error}`);
|
||||
debug(`Failed to sync account ${this.account.email}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@ import { NotificationService } from '@/main/services/notification-service';
|
||||
import { eventBus } from '@/shared/lib/event-bus';
|
||||
import { AppPlatform } from '@/shared/types/apps';
|
||||
|
||||
const debug = createDebugger('desktop:service:app');
|
||||
|
||||
export class AppService {
|
||||
private readonly debug = createDebugger('desktop:service:app');
|
||||
private readonly servers: Map<string, ServerService> = new Map();
|
||||
private readonly accounts: Map<string, AccountService> = new Map();
|
||||
private readonly cleanupEventLoop: EventLoop;
|
||||
@@ -65,7 +66,7 @@ export class AppService {
|
||||
}
|
||||
|
||||
public async migrate(): Promise<void> {
|
||||
this.debug('Migrating app database');
|
||||
debug('Migrating app database');
|
||||
|
||||
const migrator = new Migrator({
|
||||
db: this.database,
|
||||
@@ -202,7 +203,7 @@ export class AppService {
|
||||
}
|
||||
|
||||
private async syncDeletedTokens(): Promise<void> {
|
||||
this.debug('Syncing deleted tokens');
|
||||
debug('Syncing deleted tokens');
|
||||
|
||||
const deletedTokens = await this.database
|
||||
.selectFrom('deleted_tokens')
|
||||
@@ -216,14 +217,14 @@ export class AppService {
|
||||
.execute();
|
||||
|
||||
if (deletedTokens.length === 0) {
|
||||
this.debug('No deleted tokens found');
|
||||
debug('No deleted tokens found');
|
||||
return;
|
||||
}
|
||||
|
||||
for (const deletedToken of deletedTokens) {
|
||||
const serverService = this.servers.get(deletedToken.domain);
|
||||
if (!serverService || !serverService.isAvailable) {
|
||||
this.debug(
|
||||
debug(
|
||||
`Server ${deletedToken.domain} is not available for logging out account ${deletedToken.account_id}`
|
||||
);
|
||||
continue;
|
||||
@@ -242,7 +243,7 @@ export class AppService {
|
||||
.where('account_id', '=', deletedToken.account_id)
|
||||
.execute();
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Logged out account ${deletedToken.account_id} from server ${deletedToken.domain}`
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -252,7 +253,7 @@ export class AppService {
|
||||
parsedError.code === ApiErrorCode.AccountNotFound ||
|
||||
parsedError.code === ApiErrorCode.DeviceNotFound
|
||||
) {
|
||||
this.debug(
|
||||
debug(
|
||||
`Account ${deletedToken.account_id} is already logged out, skipping...`
|
||||
);
|
||||
|
||||
@@ -265,7 +266,7 @@ export class AppService {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Failed to logout account ${deletedToken.account_id} from server ${deletedToken.domain}`,
|
||||
error
|
||||
);
|
||||
|
||||
@@ -9,8 +9,9 @@ import {
|
||||
import { mapAppMetadata } from '@/main/lib/mappers';
|
||||
import { eventBus } from '@/shared/lib/event-bus';
|
||||
|
||||
const debug = createDebugger('desktop:service:metadata');
|
||||
|
||||
export class MetadataService {
|
||||
private readonly debug = createDebugger('desktop:service:metadata');
|
||||
private readonly app: AppService;
|
||||
|
||||
constructor(app: AppService) {
|
||||
@@ -46,7 +47,7 @@ export class MetadataService {
|
||||
key: K,
|
||||
value: AppMetadataMap[K]['value']
|
||||
) {
|
||||
this.debug(`Setting metadata key ${key} to value ${value}`);
|
||||
debug(`Setting metadata key ${key} to value ${value}`);
|
||||
|
||||
const createdMetadata = await this.app.database
|
||||
.insertInto('metadata')
|
||||
@@ -75,7 +76,7 @@ export class MetadataService {
|
||||
}
|
||||
|
||||
public async delete(key: string) {
|
||||
this.debug(`Deleting metadata key ${key}`);
|
||||
debug(`Deleting metadata key ${key}`);
|
||||
|
||||
const deletedMetadata = await this.app.database
|
||||
.deleteFrom('metadata')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createDebugger, ServerConfig } from '@colanode/core';
|
||||
import axios from 'axios';
|
||||
import axios, { isAxiosError } from 'axios';
|
||||
import ms from 'ms';
|
||||
|
||||
import { eventBus } from '@/shared/lib/event-bus';
|
||||
@@ -15,8 +15,9 @@ type ServerState = {
|
||||
count: number;
|
||||
};
|
||||
|
||||
const debug = createDebugger('desktop:service:server');
|
||||
|
||||
export class ServerService {
|
||||
private readonly debug = createDebugger('desktop:service:server');
|
||||
private readonly appService: AppService;
|
||||
|
||||
private state: ServerState | null = null;
|
||||
@@ -69,7 +70,7 @@ export class ServerService {
|
||||
});
|
||||
}
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Server ${this.server.domain} is ${isAvailable ? 'available' : 'unavailable'}`
|
||||
);
|
||||
|
||||
@@ -105,11 +106,19 @@ export class ServerService {
|
||||
const baseUrl = this.buildApiBaseUrl(domain);
|
||||
const configUrl = `${baseUrl}/v1/config`;
|
||||
try {
|
||||
const { status, data } = await axios.get<ServerConfig>(configUrl);
|
||||
return status === 200 ? data : null;
|
||||
} catch {
|
||||
return null;
|
||||
const { data } = await axios.get<ServerConfig>(configUrl);
|
||||
return data;
|
||||
} catch (error) {
|
||||
if (isAxiosError(error)) {
|
||||
debug(
|
||||
`Server ${domain} is unavailable. Code: ${error.code}, Message: ${error.message}`
|
||||
);
|
||||
} else {
|
||||
debug(`Server ${domain} is unavailable. Unknown error: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static buildApiBaseUrl(domain: string) {
|
||||
|
||||
@@ -4,8 +4,9 @@ import { eventBus } from '@/shared/lib/event-bus';
|
||||
import { WorkspaceService } from '@/main/services/workspaces/workspace-service';
|
||||
import { SelectCollaboration } from '@/main/databases/workspace';
|
||||
|
||||
const debug = createDebugger('desktop:service:collaboration');
|
||||
|
||||
export class CollaborationService {
|
||||
private readonly debug = createDebugger('desktop:service:collaboration');
|
||||
private readonly workspace: WorkspaceService;
|
||||
private readonly collaborations = new Map<string, SelectCollaboration>();
|
||||
|
||||
@@ -35,7 +36,7 @@ export class CollaborationService {
|
||||
}
|
||||
|
||||
public async syncServerCollaboration(collaboration: SyncCollaborationData) {
|
||||
this.debug(
|
||||
debug(
|
||||
`Applying server collaboration: ${collaboration.nodeId} for workspace ${this.workspace.id}`
|
||||
);
|
||||
|
||||
|
||||
@@ -33,8 +33,9 @@ import {
|
||||
|
||||
const UPDATE_RETRIES_LIMIT = 10;
|
||||
|
||||
const debug = createDebugger('desktop:service:document');
|
||||
|
||||
export class DocumentService {
|
||||
private readonly debug = createDebugger('desktop:service:document');
|
||||
private readonly workspace: WorkspaceService;
|
||||
|
||||
constructor(workspaceService: WorkspaceService) {
|
||||
@@ -92,7 +93,7 @@ export class DocumentService {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.debug(`Failed to update document ${node.id}: ${error}`);
|
||||
debug(`Failed to update document ${node.id}: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -401,9 +402,7 @@ export class DocumentService {
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
this.debug(
|
||||
`Failed to revert document update ${data.documentId}: ${error}`
|
||||
);
|
||||
debug(`Failed to revert document update ${data.documentId}: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -604,7 +603,7 @@ export class DocumentService {
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
this.debug(`Failed to sync document update ${data.id}: ${error}`);
|
||||
debug(`Failed to sync document update ${data.id}: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,9 @@ import { LocalFileNode } from '@/shared/types/nodes';
|
||||
const UPLOAD_RETRIES_LIMIT = 10;
|
||||
const DOWNLOAD_RETRIES_LIMIT = 10;
|
||||
|
||||
const debug = createDebugger('desktop:service:file');
|
||||
|
||||
export class FileService {
|
||||
private readonly debug = createDebugger('desktop:service:file');
|
||||
private readonly workspace: WorkspaceService;
|
||||
private readonly filesDir: string;
|
||||
private readonly tempFilesDir: string;
|
||||
@@ -217,7 +218,7 @@ export class FileService {
|
||||
fs.mkdirSync(this.filesDir, { recursive: true });
|
||||
}
|
||||
|
||||
this.debug(`Copying file ${filePath} to ${destinationFilePath}`);
|
||||
debug(`Copying file ${filePath} to ${destinationFilePath}`);
|
||||
fs.copyFileSync(filePath, destinationFilePath);
|
||||
|
||||
// check if the file is in the temp files directory. If it is in
|
||||
@@ -248,7 +249,7 @@ export class FileService {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(`Uploading files for workspace ${this.workspace.id}`);
|
||||
debug(`Uploading files for workspace ${this.workspace.id}`);
|
||||
|
||||
const uploads = await this.workspace.database
|
||||
.selectFrom('file_states')
|
||||
@@ -267,9 +268,7 @@ export class FileService {
|
||||
|
||||
private async uploadFile(state: SelectFileState): Promise<void> {
|
||||
if (state.upload_retries && state.upload_retries >= UPLOAD_RETRIES_LIMIT) {
|
||||
this.debug(
|
||||
`File ${state.id} upload retries limit reached, marking as failed`
|
||||
);
|
||||
debug(`File ${state.id} upload retries limit reached, marking as failed`);
|
||||
|
||||
const updatedFileState = await this.workspace.database
|
||||
.updateTable('file_states')
|
||||
@@ -336,7 +335,7 @@ export class FileService {
|
||||
const filePath = this.buildFilePath(file.id, file.attributes.extension);
|
||||
|
||||
if (!fs.existsSync(filePath)) {
|
||||
this.debug(`File ${file.id} not found, deleting from database`);
|
||||
debug(`File ${file.id} not found, deleting from database`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -418,7 +417,7 @@ export class FileService {
|
||||
});
|
||||
}
|
||||
|
||||
this.debug(`File ${file.id} uploaded successfully`);
|
||||
debug(`File ${file.id} uploaded successfully`);
|
||||
} catch {
|
||||
const updatedFileState = await this.workspace.database
|
||||
.updateTable('file_states')
|
||||
@@ -443,7 +442,7 @@ export class FileService {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(`Downloading files for workspace ${this.workspace.id}`);
|
||||
debug(`Downloading files for workspace ${this.workspace.id}`);
|
||||
|
||||
const downloads = await this.workspace.database
|
||||
.selectFrom('file_states')
|
||||
@@ -465,7 +464,7 @@ export class FileService {
|
||||
fileState.download_retries &&
|
||||
fileState.download_retries >= DOWNLOAD_RETRIES_LIMIT
|
||||
) {
|
||||
this.debug(
|
||||
debug(
|
||||
`File ${fileState.id} download retries limit reached, marking as failed`
|
||||
);
|
||||
|
||||
@@ -620,7 +619,7 @@ export class FileService {
|
||||
}
|
||||
|
||||
public async cleanDeletedFiles(): Promise<void> {
|
||||
this.debug(`Checking deleted files for workspace ${this.workspace.id}`);
|
||||
debug(`Checking deleted files for workspace ${this.workspace.id}`);
|
||||
|
||||
const fsFiles = fs.readdirSync(this.filesDir);
|
||||
while (fsFiles.length > 0) {
|
||||
@@ -652,7 +651,7 @@ export class FileService {
|
||||
}
|
||||
|
||||
public async cleanTempFiles(): Promise<void> {
|
||||
this.debug(`Checking temp files for workspace ${this.workspace.id}`);
|
||||
debug(`Checking temp files for workspace ${this.workspace.id}`);
|
||||
|
||||
if (!fs.existsSync(this.tempFilesDir)) {
|
||||
return;
|
||||
@@ -668,9 +667,9 @@ export class FileService {
|
||||
if (stats.mtimeMs < oneDayAgo) {
|
||||
try {
|
||||
fs.unlinkSync(filePath);
|
||||
this.debug(`Deleted old temp file: ${filePath}`);
|
||||
debug(`Deleted old temp file: ${filePath}`);
|
||||
} catch (error) {
|
||||
this.debug(`Failed to delete temp file: ${filePath}`, error);
|
||||
debug(`Failed to delete temp file: ${filePath}`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,9 @@ import { EventLoop } from '@/main/lib/event-loop';
|
||||
const READ_SIZE = 500;
|
||||
const BATCH_SIZE = 50;
|
||||
|
||||
const debug = createDebugger('desktop:service:mutation');
|
||||
|
||||
export class MutationService {
|
||||
private readonly debug = createDebugger('desktop:service:mutation');
|
||||
private readonly workspace: WorkspaceService;
|
||||
private readonly eventLoop: EventLoop;
|
||||
|
||||
@@ -41,7 +42,7 @@ export class MutationService {
|
||||
|
||||
await this.revertInvalidMutations();
|
||||
} catch (error) {
|
||||
this.debug(`Error syncing mutations: ${error}`);
|
||||
debug(`Error syncing mutations: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +73,7 @@ export class MutationService {
|
||||
);
|
||||
}
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Sending ${pendingMutations.length} local pending mutations for user ${this.workspace.id}`
|
||||
);
|
||||
|
||||
@@ -83,7 +84,7 @@ export class MutationService {
|
||||
while (validMutations.length > 0) {
|
||||
const batch = validMutations.splice(0, BATCH_SIZE);
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Sending batch ${currentBatch++} of ${totalBatches} mutations for user ${this.workspace.id}`
|
||||
);
|
||||
|
||||
@@ -115,7 +116,7 @@ export class MutationService {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.debug(
|
||||
debug(
|
||||
`Failed to send local pending mutations for user ${this.workspace.id}: ${error}`
|
||||
);
|
||||
|
||||
@@ -136,7 +137,7 @@ export class MutationService {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Reverting ${invalidMutations.length} invalid mutations for workspace ${this.workspace.id}`
|
||||
);
|
||||
|
||||
@@ -170,7 +171,7 @@ export class MutationService {
|
||||
mutationIds: string[],
|
||||
reason: string
|
||||
): Promise<void> {
|
||||
this.debug(
|
||||
debug(
|
||||
`Deleting ${mutationIds.length} local mutations for user ${this.workspace.id}. Reason: ${reason}`
|
||||
);
|
||||
|
||||
@@ -181,7 +182,7 @@ export class MutationService {
|
||||
}
|
||||
|
||||
private async markMutationsAsFailed(mutationIds: string[]): Promise<void> {
|
||||
this.debug(
|
||||
debug(
|
||||
`Marking ${mutationIds.length} local pending mutations as failed for user ${this.workspace.id}`
|
||||
);
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@ import { WorkspaceService } from '@/main/services/workspaces/workspace-service';
|
||||
import { eventBus } from '@/shared/lib/event-bus';
|
||||
import { mapNodeInteraction } from '@/main/lib/mappers';
|
||||
|
||||
const debug = createDebugger('desktop:service:node-interaction');
|
||||
|
||||
export class NodeInteractionService {
|
||||
private readonly debug = createDebugger('desktop:service:node-interaction');
|
||||
private readonly workspace: WorkspaceService;
|
||||
|
||||
constructor(workspaceService: WorkspaceService) {
|
||||
@@ -25,7 +26,7 @@ export class NodeInteractionService {
|
||||
const revision = BigInt(nodeInteraction.revision);
|
||||
if (existingNodeInteraction) {
|
||||
if (existingNodeInteraction.revision === revision) {
|
||||
this.debug(
|
||||
debug(
|
||||
`Server node interaction for node ${nodeInteraction.nodeId} is already synced`
|
||||
);
|
||||
return;
|
||||
@@ -74,7 +75,7 @@ export class NodeInteractionService {
|
||||
nodeInteraction: mapNodeInteraction(upsertedNodeInteraction),
|
||||
});
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Server node interaction for node ${nodeInteraction.nodeId} has been synced`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ import { SelectNodeReaction } from '@/main/databases/workspace';
|
||||
import { MutationErrorCode, MutationError } from '@/shared/mutations';
|
||||
import { fetchNodeTree } from '@/main/lib/utils';
|
||||
|
||||
const debug = createDebugger('desktop:service:node-reaction');
|
||||
|
||||
export class NodeReactionService {
|
||||
private readonly debug = createDebugger('desktop:service:node-reaction');
|
||||
private readonly workspace: WorkspaceService;
|
||||
|
||||
constructor(workspaceService: WorkspaceService) {
|
||||
@@ -252,7 +253,7 @@ export class NodeReactionService {
|
||||
});
|
||||
}
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Server node reaction for node ${nodeReaction.nodeId} has been synced`
|
||||
);
|
||||
return;
|
||||
@@ -269,7 +270,7 @@ export class NodeReactionService {
|
||||
const revision = BigInt(nodeReaction.revision);
|
||||
if (existingNodeReaction) {
|
||||
if (existingNodeReaction.revision === revision) {
|
||||
this.debug(
|
||||
debug(
|
||||
`Server node reaction for node ${nodeReaction.nodeId} is already synced`
|
||||
);
|
||||
return;
|
||||
@@ -290,7 +291,7 @@ export class NodeReactionService {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Server node reaction for node ${nodeReaction.nodeId} has been synced`
|
||||
);
|
||||
return;
|
||||
@@ -325,7 +326,7 @@ export class NodeReactionService {
|
||||
nodeReaction: mapNodeReaction(createdNodeReaction),
|
||||
});
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Server node reaction for node ${nodeReaction.nodeId} has been synced`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,8 +44,9 @@ export type UpdateNodeResult =
|
||||
| 'failed'
|
||||
| 'invalid_attributes';
|
||||
|
||||
const debug = createDebugger('desktop:service:node');
|
||||
|
||||
export class NodeService {
|
||||
private readonly debug = createDebugger('desktop:service:node');
|
||||
private readonly workspace: WorkspaceService;
|
||||
|
||||
constructor(workspaceService: WorkspaceService) {
|
||||
@@ -53,7 +54,7 @@ export class NodeService {
|
||||
}
|
||||
|
||||
public async createNode(input: CreateNodeInput): Promise<SelectNode> {
|
||||
this.debug(`Creating ${Array.isArray(input) ? 'nodes' : 'node'}`);
|
||||
debug(`Creating ${Array.isArray(input) ? 'nodes' : 'node'}`);
|
||||
|
||||
const tree = input.parentId
|
||||
? await fetchNodeTree(this.workspace.database, input.parentId)
|
||||
@@ -191,7 +192,7 @@ export class NodeService {
|
||||
throw new Error('Failed to create mutation');
|
||||
}
|
||||
|
||||
this.debug(`Created node ${createdNode.id} with type ${createdNode.type}`);
|
||||
debug(`Created node ${createdNode.id} with type ${createdNode.type}`);
|
||||
|
||||
eventBus.publish({
|
||||
type: 'node_created',
|
||||
@@ -231,7 +232,7 @@ export class NodeService {
|
||||
nodeId: string,
|
||||
updater: (attributes: T) => T
|
||||
): Promise<UpdateNodeResult | null> {
|
||||
this.debug(`Updating node ${nodeId}`);
|
||||
debug(`Updating node ${nodeId}`);
|
||||
|
||||
const tree = await fetchNodeTree(this.workspace.database, nodeId);
|
||||
const node = tree[tree.length - 1];
|
||||
@@ -381,9 +382,7 @@ export class NodeService {
|
||||
});
|
||||
|
||||
if (updatedNode) {
|
||||
this.debug(
|
||||
`Updated node ${updatedNode.id} with type ${updatedNode.type}`
|
||||
);
|
||||
debug(`Updated node ${updatedNode.id} with type ${updatedNode.type}`);
|
||||
|
||||
eventBus.publish({
|
||||
type: 'node_updated',
|
||||
@@ -392,7 +391,7 @@ export class NodeService {
|
||||
node: mapNode(updatedNode),
|
||||
});
|
||||
} else {
|
||||
this.debug(`Failed to update node ${nodeId}`);
|
||||
debug(`Failed to update node ${nodeId}`);
|
||||
}
|
||||
|
||||
if (createdMutation) {
|
||||
@@ -491,9 +490,7 @@ export class NodeService {
|
||||
});
|
||||
|
||||
if (deletedNode) {
|
||||
this.debug(
|
||||
`Deleted node ${deletedNode.id} with type ${deletedNode.type}`
|
||||
);
|
||||
debug(`Deleted node ${deletedNode.id} with type ${deletedNode.type}`);
|
||||
|
||||
eventBus.publish({
|
||||
type: 'node_deleted',
|
||||
@@ -502,7 +499,7 @@ export class NodeService {
|
||||
node: mapNode(deletedNode),
|
||||
});
|
||||
} else {
|
||||
this.debug(`Failed to delete node ${nodeId}`);
|
||||
debug(`Failed to delete node ${nodeId}`);
|
||||
}
|
||||
|
||||
if (createdMutation) {
|
||||
@@ -531,7 +528,7 @@ export class NodeService {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.debug(`Failed to update node ${update.id}: ${error}`);
|
||||
debug(`Failed to update node ${update.id}: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -611,11 +608,11 @@ export class NodeService {
|
||||
});
|
||||
|
||||
if (!createdNode) {
|
||||
this.debug(`Failed to create node ${update.nodeId}`);
|
||||
debug(`Failed to create node ${update.nodeId}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.debug(`Created node ${createdNode.id} with type ${createdNode.type}`);
|
||||
debug(`Created node ${createdNode.id} with type ${createdNode.type}`);
|
||||
|
||||
eventBus.publish({
|
||||
type: 'node_created',
|
||||
@@ -762,11 +759,11 @@ export class NodeService {
|
||||
});
|
||||
|
||||
if (!updatedNode) {
|
||||
this.debug(`Failed to update node ${existingNode.id}`);
|
||||
debug(`Failed to update node ${existingNode.id}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.debug(`Updated node ${updatedNode.id} with type ${updatedNode.type}`);
|
||||
debug(`Updated node ${updatedNode.id} with type ${updatedNode.type}`);
|
||||
|
||||
eventBus.publish({
|
||||
type: 'node_updated',
|
||||
@@ -797,7 +794,7 @@ export class NodeService {
|
||||
}
|
||||
|
||||
public async syncServerNodeDelete(tombstone: SyncNodeTombstoneData) {
|
||||
this.debug(
|
||||
debug(
|
||||
`Applying server delete transaction ${tombstone.id} for node ${tombstone.id}`
|
||||
);
|
||||
|
||||
|
||||
@@ -39,8 +39,9 @@ type SyncHandlers = {
|
||||
documentUpdates: (data: SyncDocumentUpdateData) => Promise<void>;
|
||||
};
|
||||
|
||||
const debug = createDebugger('desktop:service:sync');
|
||||
|
||||
export class SyncService {
|
||||
private readonly debug = createDebugger('desktop:service:sync');
|
||||
private readonly workspace: WorkspaceService;
|
||||
|
||||
private readonly rootSynchronizers: Map<string, RootSynchronizers> =
|
||||
@@ -98,7 +99,7 @@ export class SyncService {
|
||||
}
|
||||
|
||||
public async init() {
|
||||
this.debug(`Initializing sync service for workspace ${this.workspace.id}`);
|
||||
debug(`Initializing sync service for workspace ${this.workspace.id}`);
|
||||
|
||||
if (!this.userSynchronizer) {
|
||||
this.userSynchronizer = new Synchronizer(
|
||||
@@ -152,7 +153,7 @@ export class SyncService {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(
|
||||
debug(
|
||||
`Initializing root synchronizers for root ${rootId} in workspace ${this.workspace.id}`
|
||||
);
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@ import { eventBus } from '@/shared/lib/event-bus';
|
||||
|
||||
export type SynchronizerStatus = 'idle' | 'waiting' | 'processing';
|
||||
|
||||
const debug = createDebugger('desktop:synchronizer');
|
||||
|
||||
export class Synchronizer<TInput extends SynchronizerInput> {
|
||||
private readonly debug = createDebugger('desktop:synchronizer');
|
||||
private readonly id: string;
|
||||
private readonly input: TInput;
|
||||
private readonly workspace: WorkspaceService;
|
||||
@@ -112,7 +113,7 @@ export class Synchronizer<TInput extends SynchronizerInput> {
|
||||
lastCursor = BigInt(item.cursor);
|
||||
}
|
||||
} catch (error) {
|
||||
this.debug(`Error consuming items: ${error}`);
|
||||
debug(`Error consuming items: ${error}`);
|
||||
} finally {
|
||||
if (lastCursor !== null) {
|
||||
this.cursor = lastCursor;
|
||||
@@ -133,7 +134,7 @@ export class Synchronizer<TInput extends SynchronizerInput> {
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(`Initializing consumer for ${this.input.type}`);
|
||||
debug(`Initializing consumer for ${this.input.type}`);
|
||||
|
||||
const message: SynchronizerInputMessage = {
|
||||
id: this.id,
|
||||
|
||||
@@ -4,8 +4,9 @@ import { mapUser } from '@/main/lib/mappers';
|
||||
import { eventBus } from '@/shared/lib/event-bus';
|
||||
import { WorkspaceService } from '@/main/services/workspaces/workspace-service';
|
||||
|
||||
const debug = createDebugger('desktop:service:user');
|
||||
|
||||
export class UserService {
|
||||
private readonly debug = createDebugger('desktop:service:user');
|
||||
private readonly workspace: WorkspaceService;
|
||||
|
||||
constructor(workspaceService: WorkspaceService) {
|
||||
@@ -13,9 +14,7 @@ export class UserService {
|
||||
}
|
||||
|
||||
public async syncServerUser(user: SyncUserData) {
|
||||
this.debug(
|
||||
`Syncing server user ${user.id} in workspace ${this.workspace.id}`
|
||||
);
|
||||
debug(`Syncing server user ${user.id} in workspace ${this.workspace.id}`);
|
||||
|
||||
const createdUser = await this.workspace.database
|
||||
.insertInto('users')
|
||||
|
||||
@@ -25,8 +25,9 @@ import { DocumentService } from '@/main/services/workspaces/document-service';
|
||||
import { NodeCountersService } from '@/main/services/workspaces/node-counters-service';
|
||||
import { eventBus } from '@/shared/lib/event-bus';
|
||||
|
||||
const debug = createDebugger('desktop:service:workspace');
|
||||
|
||||
export class WorkspaceService {
|
||||
private readonly debug = createDebugger('desktop:service:workspace');
|
||||
private readonly workspace: Workspace;
|
||||
|
||||
public readonly database: Kysely<WorkspaceDatabaseSchema>;
|
||||
@@ -44,7 +45,7 @@ export class WorkspaceService {
|
||||
public readonly nodeCounters: NodeCountersService;
|
||||
|
||||
constructor(workspace: Workspace, account: AccountService) {
|
||||
this.debug(`Initializing workspace service ${workspace.id}`);
|
||||
debug(`Initializing workspace service ${workspace.id}`);
|
||||
|
||||
this.workspace = workspace;
|
||||
this.account = account;
|
||||
@@ -120,9 +121,7 @@ export class WorkspaceService {
|
||||
}
|
||||
|
||||
private async migrate(): Promise<void> {
|
||||
this.debug(
|
||||
`Migrating workspace database for workspace ${this.workspace.id}`
|
||||
);
|
||||
debug(`Migrating workspace database for workspace ${this.workspace.id}`);
|
||||
|
||||
const migrator = new Migrator({
|
||||
db: this.database,
|
||||
@@ -169,7 +168,7 @@ export class WorkspaceService {
|
||||
workspace: this.workspace,
|
||||
});
|
||||
} catch (error) {
|
||||
this.debug(`Error deleting workspace ${this.workspace.id}: ${error}`);
|
||||
debug(`Error deleting workspace ${this.workspace.id}: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user