feat: debug logger with levels (#1165)
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
"@affine/datacenter": "workspace:*",
|
"@affine/datacenter": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@affine/store": "workspace:*",
|
"@affine/store": "workspace:*",
|
||||||
|
"@affine/debug": "workspace:*",
|
||||||
"@blocksuite/blocks": "0.4.1",
|
"@blocksuite/blocks": "0.4.1",
|
||||||
"@blocksuite/editor": "0.4.1",
|
"@blocksuite/editor": "0.4.1",
|
||||||
"@blocksuite/global": "0.4.1",
|
"@blocksuite/global": "0.4.1",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
|
"@affine/debug": "workspace:*",
|
||||||
"@blocksuite/blocks": "0.4.1",
|
"@blocksuite/blocks": "0.4.1",
|
||||||
"@blocksuite/editor": "0.4.1",
|
"@blocksuite/editor": "0.4.1",
|
||||||
"@blocksuite/global": "0.4.1",
|
"@blocksuite/global": "0.4.1",
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
"url": "git+https://github.com/toeverything/AFFiNE.git"
|
"url": "git+https://github.com/toeverything/AFFiNE.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/debug": "^4.1.7",
|
|
||||||
"fake-indexeddb": "4.0.1",
|
"fake-indexeddb": "4.0.1",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
@@ -17,7 +16,7 @@
|
|||||||
"@blocksuite/blocks": "0.4.1",
|
"@blocksuite/blocks": "0.4.1",
|
||||||
"@blocksuite/store": "0.4.1",
|
"@blocksuite/store": "0.4.1",
|
||||||
"@tauri-apps/api": "^1.2.0",
|
"@tauri-apps/api": "^1.2.0",
|
||||||
"debug": "^4.3.4",
|
"@affine/debug": "workspace:*",
|
||||||
"encoding": "^0.1.13",
|
"encoding": "^0.1.13",
|
||||||
"firebase": "^9.17.1",
|
"firebase": "^9.17.1",
|
||||||
"idb-keyval": "^6.2.0",
|
"idb-keyval": "^6.2.0",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
import { DebugLogger } from '@affine/debug';
|
||||||
import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store';
|
import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
|
||||||
import { getLogger } from './logger';
|
|
||||||
import { MessageCenter } from './message';
|
import { MessageCenter } from './message';
|
||||||
import { AffineProvider } from './provider';
|
import { AffineProvider } from './provider';
|
||||||
import type {
|
import type {
|
||||||
@@ -23,7 +23,7 @@ import { WorkspaceUnitCollection } from './workspace-unit-collection';
|
|||||||
|
|
||||||
export class DataCenter {
|
export class DataCenter {
|
||||||
private readonly _workspaceUnitCollection = new WorkspaceUnitCollection();
|
private readonly _workspaceUnitCollection = new WorkspaceUnitCollection();
|
||||||
private readonly _logger = getLogger('dc');
|
private readonly _logger = new DebugLogger('datacenter');
|
||||||
private _workspaceInstances: Map<string, BlocksuiteWorkspace> = new Map();
|
private _workspaceInstances: Map<string, BlocksuiteWorkspace> = new Map();
|
||||||
private _messageCenter = MessageCenter.getInstance();
|
private _messageCenter = MessageCenter.getInstance();
|
||||||
|
|
||||||
@@ -33,19 +33,12 @@ export class DataCenter {
|
|||||||
private _mainProvider?: BaseProvider;
|
private _mainProvider?: BaseProvider;
|
||||||
providerMap: Map<string, BaseProvider> = new Map();
|
providerMap: Map<string, BaseProvider> = new Map();
|
||||||
|
|
||||||
private constructor(debug: boolean) {
|
|
||||||
this._logger.enabled = debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
static initEmpty() {
|
static initEmpty() {
|
||||||
return new DataCenter(false);
|
return new DataCenter();
|
||||||
}
|
}
|
||||||
|
|
||||||
static async init(
|
static async init(exclude: 'affine'[] = []): Promise<DataCenter> {
|
||||||
debug: boolean,
|
const dc = new DataCenter();
|
||||||
exclude: 'affine'[] = []
|
|
||||||
): Promise<DataCenter> {
|
|
||||||
const dc = new DataCenter(debug);
|
|
||||||
const getInitParams = () => {
|
const getInitParams = () => {
|
||||||
return {
|
return {
|
||||||
logger: dc._logger,
|
logger: dc._logger,
|
||||||
@@ -182,7 +175,10 @@ export class DataCenter {
|
|||||||
}
|
}
|
||||||
const provider = this.providerMap.get(workspaceUnit.provider);
|
const provider = this.providerMap.get(workspaceUnit.provider);
|
||||||
assert(provider, `provide '${workspaceUnit.provider}' is not registered`);
|
assert(provider, `provide '${workspaceUnit.provider}' is not registered`);
|
||||||
this._logger(`Loading ${workspaceUnit.provider} workspace: `, workspaceId);
|
this._logger.debug(
|
||||||
|
`Loading ${workspaceUnit.provider} workspace: `,
|
||||||
|
workspaceId
|
||||||
|
);
|
||||||
|
|
||||||
const workspace = this._getBlocksuiteWorkspace(workspaceId);
|
const workspace = this._getBlocksuiteWorkspace(workspaceId);
|
||||||
this._workspaceInstances.set(workspaceId, workspace);
|
this._workspaceInstances.set(workspaceId, workspace);
|
||||||
@@ -350,7 +346,7 @@ export class DataCenter {
|
|||||||
providerId = 'affine'
|
providerId = 'affine'
|
||||||
) {
|
) {
|
||||||
if (workspaceUnit.provider === providerId) {
|
if (workspaceUnit.provider === providerId) {
|
||||||
this._logger('Workspace provider is same');
|
this._logger.error('Workspace provider is same');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const provider = this.providerMap.get(providerId);
|
const provider = this.providerMap.get(providerId);
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import { DataCenter } from './datacenter';
|
|||||||
const _initializeDataCenter = () => {
|
const _initializeDataCenter = () => {
|
||||||
let _dataCenterInstance: Promise<DataCenter>;
|
let _dataCenterInstance: Promise<DataCenter>;
|
||||||
|
|
||||||
return (debug = true) => {
|
return () => {
|
||||||
if (!_dataCenterInstance) {
|
if (!_dataCenterInstance) {
|
||||||
_dataCenterInstance = DataCenter.init(debug);
|
_dataCenterInstance = DataCenter.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _dataCenterInstance;
|
return _dataCenterInstance;
|
||||||
@@ -15,7 +15,6 @@ const _initializeDataCenter = () => {
|
|||||||
export const getDataCenter = _initializeDataCenter();
|
export const getDataCenter = _initializeDataCenter();
|
||||||
|
|
||||||
export { DataCenter };
|
export { DataCenter };
|
||||||
export { getLogger } from './logger';
|
|
||||||
export * from './message';
|
export * from './message';
|
||||||
export { AffineProvider } from './provider/affine';
|
export { AffineProvider } from './provider/affine';
|
||||||
export * from './provider/affine/apis';
|
export * from './provider/affine/apis';
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
import debug from 'debug';
|
|
||||||
|
|
||||||
export function getLogger(namespace: string) {
|
|
||||||
const logger = debug(namespace);
|
|
||||||
logger.log = console.log.bind(console);
|
|
||||||
return logger;
|
|
||||||
}
|
|
||||||
@@ -86,7 +86,6 @@ export class AffineProvider extends BaseProvider {
|
|||||||
`${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${
|
`${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${
|
||||||
window.location.host
|
window.location.host
|
||||||
}/api/global/sync/`,
|
}/api/global/sync/`,
|
||||||
this._logger,
|
|
||||||
this._apis.auth,
|
this._apis.auth,
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
@@ -115,7 +114,7 @@ export class AffineProvider extends BaseProvider {
|
|||||||
ws_details,
|
ws_details,
|
||||||
metadata,
|
metadata,
|
||||||
}: ChannelMessage) {
|
}: ChannelMessage) {
|
||||||
this._logger('receive server message');
|
this._logger.debug('receive server message');
|
||||||
const newlyCreatedWorkspaces: WorkspaceUnit[] = [];
|
const newlyCreatedWorkspaces: WorkspaceUnit[] = [];
|
||||||
const currentWorkspaceIds = this._workspaces.list().map(w => w.id);
|
const currentWorkspaceIds = this._workspaces.list().map(w => w.id);
|
||||||
const newlyRemovedWorkspaceIds = currentWorkspaceIds;
|
const newlyRemovedWorkspaceIds = currentWorkspaceIds;
|
||||||
@@ -331,7 +330,7 @@ export class AffineProvider extends BaseProvider {
|
|||||||
await this.deleteWorkspace(w.id);
|
await this.deleteWorkspace(w.id);
|
||||||
this._workspaces.remove(w.id);
|
this._workspaces.remove(w.id);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this._logger('has a problem of delete workspace ', e);
|
this._logger.error('has a problem of delete workspace ', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { DebugLogger } from '@affine/debug';
|
||||||
import { initializeApp } from 'firebase/app';
|
import { initializeApp } from 'firebase/app';
|
||||||
import type { User } from 'firebase/auth';
|
import type { User } from 'firebase/auth';
|
||||||
import {
|
import {
|
||||||
@@ -10,7 +11,6 @@ import {
|
|||||||
import { decode } from 'js-base64';
|
import { decode } from 'js-base64';
|
||||||
import { KyInstance } from 'ky/distribution/types/ky';
|
import { KyInstance } from 'ky/distribution/types/ky';
|
||||||
|
|
||||||
import { getLogger } from '../../../logger';
|
|
||||||
import { storage } from '../storage';
|
import { storage } from '../storage';
|
||||||
|
|
||||||
export interface AccessTokenMessage {
|
export interface AccessTokenMessage {
|
||||||
@@ -58,7 +58,7 @@ export class GoogleAuth {
|
|||||||
private readonly _doLogin: ReturnType<typeof createDoLogin>;
|
private readonly _doLogin: ReturnType<typeof createDoLogin>;
|
||||||
|
|
||||||
constructor(bareClient: KyInstance) {
|
constructor(bareClient: KyInstance) {
|
||||||
this._logger = getLogger('token');
|
this._logger = new DebugLogger('token');
|
||||||
this._logger.enabled = true;
|
this._logger.enabled = true;
|
||||||
this._doLogin = createDoLogin(bareClient);
|
this._doLogin = createDoLogin(bareClient);
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ export class GoogleAuth {
|
|||||||
const login: LoginResponse = JSON.parse(loginStr);
|
const login: LoginResponse = JSON.parse(loginStr);
|
||||||
this.setLogin(login);
|
this.setLogin(login);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._logger('Failed to parse login info', err);
|
this._logger.warn('Failed to parse login info', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ export class GoogleAuth {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch {
|
} catch {
|
||||||
this._logger('Failed to refresh token');
|
this._logger.warn('Failed to refresh token');
|
||||||
} finally {
|
} finally {
|
||||||
// clear on settled
|
// clear on settled
|
||||||
this._padding = undefined;
|
this._padding = undefined;
|
||||||
@@ -191,7 +191,7 @@ export function createGoogleAuth(bareAuth: KyInstance): GoogleAuth {
|
|||||||
|
|
||||||
export const getAuthorizer = (googleAuth: GoogleAuth) => {
|
export const getAuthorizer = (googleAuth: GoogleAuth) => {
|
||||||
let _firebaseAuth: FirebaseAuth | null = null;
|
let _firebaseAuth: FirebaseAuth | null = null;
|
||||||
const logger = getLogger('authorizer');
|
const logger = new DebugLogger('authorizer');
|
||||||
|
|
||||||
// getAuth will send requests on calling thus we can lazy init it
|
// getAuth will send requests on calling thus we can lazy init it
|
||||||
const getAuth = () => {
|
const getAuth = () => {
|
||||||
@@ -211,7 +211,7 @@ export const getAuthorizer = (googleAuth: GoogleAuth) => {
|
|||||||
}
|
}
|
||||||
return _firebaseAuth;
|
return _firebaseAuth;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger(error);
|
logger.error('Failed to initialize firebase', error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
import { DebugLogger } from '@affine/debug';
|
||||||
import * as url from 'lib0/url';
|
import * as url from 'lib0/url';
|
||||||
import * as websocket from 'lib0/websocket';
|
import * as websocket from 'lib0/websocket';
|
||||||
|
|
||||||
import { Logger } from '../../types';
|
|
||||||
import { GoogleAuth } from './apis/google';
|
import { GoogleAuth } from './apis/google';
|
||||||
|
|
||||||
const RECONNECT_INTERVAL_TIME = 500;
|
const RECONNECT_INTERVAL_TIME = 500;
|
||||||
@@ -9,12 +9,11 @@ const MAX_RECONNECT_TIMES = 50;
|
|||||||
|
|
||||||
export class WebsocketClient extends websocket.WebsocketClient {
|
export class WebsocketClient extends websocket.WebsocketClient {
|
||||||
public shouldReconnect = false;
|
public shouldReconnect = false;
|
||||||
private _logger: Logger;
|
|
||||||
private _retryTimes = 0;
|
private _retryTimes = 0;
|
||||||
private _auth: GoogleAuth;
|
private _auth: GoogleAuth;
|
||||||
|
private _logger = new DebugLogger('affine:channel');
|
||||||
constructor(
|
constructor(
|
||||||
serverUrl: string,
|
serverUrl: string,
|
||||||
logger: Logger,
|
|
||||||
auth: GoogleAuth,
|
auth: GoogleAuth,
|
||||||
options?: ConstructorParameters<typeof websocket.WebsocketClient>[1] & {
|
options?: ConstructorParameters<typeof websocket.WebsocketClient>[1] & {
|
||||||
params: Record<string, string>;
|
params: Record<string, string>;
|
||||||
@@ -30,13 +29,12 @@ export class WebsocketClient extends websocket.WebsocketClient {
|
|||||||
serverUrl + '/' + (encodedParams.length === 0 ? '' : '?' + encodedParams);
|
serverUrl + '/' + (encodedParams.length === 0 ? '' : '?' + encodedParams);
|
||||||
super(newUrl, options);
|
super(newUrl, options);
|
||||||
this._auth = auth;
|
this._auth = auth;
|
||||||
this._logger = logger;
|
|
||||||
this._setupChannel();
|
this._setupChannel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setupChannel() {
|
private _setupChannel() {
|
||||||
this.on('connect', () => {
|
this.on('connect', () => {
|
||||||
this._logger('Affine channel connected');
|
this._logger.debug('Affine channel connected');
|
||||||
this.shouldReconnect = true;
|
this.shouldReconnect = true;
|
||||||
this._retryTimes = 0;
|
this._retryTimes = 0;
|
||||||
});
|
});
|
||||||
@@ -49,15 +47,17 @@ export class WebsocketClient extends websocket.WebsocketClient {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this._retryTimes <= MAX_RECONNECT_TIMES) {
|
if (this._retryTimes <= MAX_RECONNECT_TIMES) {
|
||||||
this.connect();
|
this.connect();
|
||||||
this._logger(
|
this._logger.info(
|
||||||
`try reconnect channel ${++this._retryTimes} times`
|
`try reconnect channel ${++this._retryTimes} times`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this._logger('reconnect failed, max reconnect times reached');
|
this._logger.error(
|
||||||
|
'reconnect failed, max reconnect times reached'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, RECONNECT_INTERVAL_TIME);
|
}, RECONNECT_INTERVAL_TIME);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this._logger('reconnect failed', e);
|
this._logger.error('reconnect failed', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
|
import { DebugLogger } from '@affine/debug';
|
||||||
import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store';
|
import { Workspace as BlocksuiteWorkspace } from '@blocksuite/store';
|
||||||
|
|
||||||
import { MessageCenter } from '../message';
|
import { MessageCenter } from '../message';
|
||||||
import { Logger, User } from '../types';
|
import { User } from '../types';
|
||||||
import type { WorkspaceUnit, WorkspaceUnitCtorParams } from '../workspace-unit';
|
import type { WorkspaceUnit, WorkspaceUnitCtorParams } from '../workspace-unit';
|
||||||
import type { WorkspaceUnitCollectionScope } from '../workspace-unit-collection';
|
import type { WorkspaceUnitCollectionScope } from '../workspace-unit-collection';
|
||||||
import { Member } from './affine/apis';
|
import { Member } from './affine/apis';
|
||||||
import { Permission } from './affine/apis/workspace';
|
import { Permission } from './affine/apis/workspace';
|
||||||
|
|
||||||
const defaultLogger = () => {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface ProviderConstructorParams {
|
export interface ProviderConstructorParams {
|
||||||
logger?: Logger;
|
|
||||||
workspaces: WorkspaceUnitCollectionScope;
|
workspaces: WorkspaceUnitCollectionScope;
|
||||||
messageCenter: MessageCenter;
|
messageCenter: MessageCenter;
|
||||||
}
|
}
|
||||||
@@ -23,25 +19,21 @@ export type UpdateWorkspaceMetaParams = Partial<
|
|||||||
Pick<WorkspaceUnitCtorParams, 'name' | 'avatar'>
|
Pick<WorkspaceUnitCtorParams, 'name' | 'avatar'>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export class BaseProvider {
|
export abstract class BaseProvider {
|
||||||
/** provider id */
|
/** provider id */
|
||||||
public readonly id: string = 'base';
|
public readonly id: string = 'base';
|
||||||
/** workspace unit collection */
|
/** workspace unit collection */
|
||||||
protected _workspaces!: WorkspaceUnitCollectionScope;
|
protected _workspaces!: WorkspaceUnitCollectionScope;
|
||||||
protected _logger!: Logger;
|
protected _logger: DebugLogger;
|
||||||
/** send message with message center */
|
/** send message with message center */
|
||||||
protected _sendMessage!: ReturnType<
|
protected _sendMessage!: ReturnType<
|
||||||
InstanceType<typeof MessageCenter>['getMessageSender']
|
InstanceType<typeof MessageCenter>['getMessageSender']
|
||||||
>;
|
>;
|
||||||
|
|
||||||
public constructor({
|
public constructor({ workspaces, messageCenter }: ProviderConstructorParams) {
|
||||||
logger,
|
|
||||||
workspaces,
|
|
||||||
messageCenter,
|
|
||||||
}: ProviderConstructorParams) {
|
|
||||||
this._logger = (logger || defaultLogger) as Logger;
|
|
||||||
this._workspaces = workspaces;
|
this._workspaces = workspaces;
|
||||||
this._sendMessage = messageCenter.getMessageSender(this.id);
|
this._sendMessage = messageCenter.getMessageSender(this.id);
|
||||||
|
this._logger = new DebugLogger(`provider:${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export class LocalProvider extends BaseProvider {
|
|||||||
idb = new IndexedDBProvider(workspace.room, workspace.doc);
|
idb = new IndexedDBProvider(workspace.room, workspace.doc);
|
||||||
}
|
}
|
||||||
this._idbMap.set(workspace, idb);
|
this._idbMap.set(workspace, idb);
|
||||||
this._logger('Local data loaded');
|
this._logger.debug('Local data loaded');
|
||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ export class LocalProvider extends BaseProvider {
|
|||||||
this._workspaces.add(workspaceUnits);
|
this._workspaces.add(workspaceUnits);
|
||||||
return workspaceUnits;
|
return workspaceUnits;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this._logger(`Failed to parse workspaces from storage`);
|
this._logger.error(`Failed to parse workspaces from storage`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
@@ -84,7 +84,7 @@ export class LocalProvider extends BaseProvider {
|
|||||||
this._idbMap.delete(workspace.blocksuiteWorkspace);
|
this._idbMap.delete(workspace.blocksuiteWorkspace);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this._logger(`Failed to delete workspace ${id}`);
|
this._logger.error(`Failed to delete workspace ${id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { createWorkspaceUnit } from './utils';
|
|||||||
export class TauriIPCProvider extends LocalProvider {
|
export class TauriIPCProvider extends LocalProvider {
|
||||||
public id = 'tauri-ipc';
|
public id = 'tauri-ipc';
|
||||||
static defaultUserEmail = 'xxx@xx.xx';
|
static defaultUserEmail = 'xxx@xx.xx';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* // TODO: We only have one user in this version of app client. But may support switch user later.
|
* // TODO: We only have one user in this version of app client. But may support switch user later.
|
||||||
*/
|
*/
|
||||||
@@ -79,7 +80,7 @@ export class TauriIPCProvider extends LocalProvider {
|
|||||||
workspaceID: string,
|
workspaceID: string,
|
||||||
blocksuiteWorkspace: BlocksuiteWorkspace
|
blocksuiteWorkspace: BlocksuiteWorkspace
|
||||||
) {
|
) {
|
||||||
this._logger(`Loading ${workspaceID}...`);
|
this._logger.debug(`Loading ${workspaceID}...`);
|
||||||
const result = await this.#ipc?.getYDocument({ id: workspaceID });
|
const result = await this.#ipc?.getYDocument({ id: workspaceID });
|
||||||
if (result) {
|
if (result) {
|
||||||
const updates = result.updates.map(
|
const updates = result.updates.map(
|
||||||
@@ -88,7 +89,7 @@ export class TauriIPCProvider extends LocalProvider {
|
|||||||
|
|
||||||
const mergedUpdate = Y.mergeUpdates(updates);
|
const mergedUpdate = Y.mergeUpdates(updates);
|
||||||
await applyUpdate(blocksuiteWorkspace, mergedUpdate);
|
await applyUpdate(blocksuiteWorkspace, mergedUpdate);
|
||||||
this._logger(`Loaded: ${workspaceID}`);
|
this._logger.debug(`Loaded: ${workspaceID}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ export class TauriIPCProvider extends LocalProvider {
|
|||||||
workspaceID: string,
|
workspaceID: string,
|
||||||
blocksuiteWorkspace: BlocksuiteWorkspace
|
blocksuiteWorkspace: BlocksuiteWorkspace
|
||||||
) {
|
) {
|
||||||
this._logger(`Connecting yDoc for ${workspaceID}...`);
|
this._logger.debug(`Connecting yDoc for ${workspaceID}...`);
|
||||||
blocksuiteWorkspace.doc.on('update', async (update: Uint8Array) => {
|
blocksuiteWorkspace.doc.on('update', async (update: Uint8Array) => {
|
||||||
try {
|
try {
|
||||||
const binary = Y.encodeStateAsUpdate(blocksuiteWorkspace.doc);
|
const binary = Y.encodeStateAsUpdate(blocksuiteWorkspace.doc);
|
||||||
@@ -109,7 +110,7 @@ export class TauriIPCProvider extends LocalProvider {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// TODO: write error log to disk, and add button to open them in settings panel
|
// TODO: write error log to disk, and add button to open them in settings panel
|
||||||
console.error("#yDocument.on('update'", error);
|
this._logger.error("#yDocument.on('update'", error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -134,7 +135,7 @@ export class TauriIPCProvider extends LocalProvider {
|
|||||||
public override async createWorkspace(
|
public override async createWorkspace(
|
||||||
meta: CreateWorkspaceInfoParams
|
meta: CreateWorkspaceInfoParams
|
||||||
): Promise<WorkspaceUnit | undefined> {
|
): Promise<WorkspaceUnit | undefined> {
|
||||||
this._logger('Creating client app workspace');
|
this._logger.debug('Creating client app workspace');
|
||||||
assert(this.#ipc);
|
assert(this.#ipc);
|
||||||
assert(this.#userID);
|
assert(this.#userID);
|
||||||
const { id } = await this.#ipc.createWorkspace({
|
const { id } = await this.#ipc.createWorkspace({
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { getLogger } from '../logger';
|
|
||||||
|
|
||||||
// export type WorkspaceInfo = {
|
// export type WorkspaceInfo = {
|
||||||
// name: string;
|
// name: string;
|
||||||
// id: string;
|
// id: string;
|
||||||
@@ -27,7 +25,7 @@ export type User = {
|
|||||||
|
|
||||||
// export type WorkspaceMeta = Pick<WorkspaceInfo, 'name' | 'avatar'>;
|
// export type WorkspaceMeta = Pick<WorkspaceInfo, 'name' | 'avatar'>;
|
||||||
|
|
||||||
export type Logger = ReturnType<typeof getLogger>;
|
export type Logger = typeof import('@affine/debug').DebugLogger;
|
||||||
|
|
||||||
export type Message = {
|
export type Message = {
|
||||||
code: number;
|
code: number;
|
||||||
|
|||||||
3
packages/debug/README.md
Normal file
3
packages/debug/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# @affine/debug
|
||||||
|
|
||||||
|
A common debug interface for packages in this repository.
|
||||||
14
packages/debug/package.json
Normal file
14
packages/debug/package.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "@affine/debug",
|
||||||
|
"private": true,
|
||||||
|
"main": "./src/index.ts",
|
||||||
|
"keywords": [],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/toeverything/AFFiNE.git"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/debug": "^4.1.7",
|
||||||
|
"debug": "^4.3.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
59
packages/debug/src/index.ts
Normal file
59
packages/debug/src/index.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import debug from 'debug';
|
||||||
|
|
||||||
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
||||||
|
|
||||||
|
const SESSION_KEY = 'affine:debug';
|
||||||
|
const development = process.env.NODE_ENV === 'development';
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
// enable debug logs if the URL search string contains `debug`
|
||||||
|
// e.g. http://localhost:3000/?debug
|
||||||
|
if (window.location.search.includes('debug')) {
|
||||||
|
// enable debug logs for the current session
|
||||||
|
// since the query string may be removed by the browser after navigations,
|
||||||
|
// we need to store the debug flag in sessionStorage
|
||||||
|
sessionStorage.setItem(SESSION_KEY, 'true');
|
||||||
|
}
|
||||||
|
if (sessionStorage.getItem(SESSION_KEY) === 'true' || development) {
|
||||||
|
// enable all debug logs by default
|
||||||
|
debug.enable('*');
|
||||||
|
console.warn('Debug logs enabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DebugLogger {
|
||||||
|
private _debug: debug.Debugger;
|
||||||
|
|
||||||
|
constructor(namespace: string) {
|
||||||
|
this._debug = debug(namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
set enabled(enabled: boolean) {
|
||||||
|
this._debug.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
get enabled() {
|
||||||
|
return this._debug.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(message: string, ...args: any[]) {
|
||||||
|
this.log('debug', message, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
info(message: string, ...args: any[]) {
|
||||||
|
this.log('info', message, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
warn(message: string, ...args: any[]) {
|
||||||
|
this.log('warn', message, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
error(message: string, ...args: any[]) {
|
||||||
|
this.log('error', message, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(level: LogLevel, message: string, ...args: any[]) {
|
||||||
|
this._debug.log = console[level].bind(console);
|
||||||
|
this._debug(`[${level.toUpperCase()}] ${message}`, ...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
"url": "git+https://github.com/toeverything/AFFiNE.git"
|
"url": "git+https://github.com/toeverything/AFFiNE.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@affine/debug": "workspace:*",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"i18next": "^22.4.10",
|
"i18next": "^22.4.10",
|
||||||
"react-i18next": "^12.1.5"
|
"react-i18next": "^12.1.5"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
"main": "./src/index.ts",
|
"main": "./src/index.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@affine/datacenter": "workspace:*",
|
"@affine/datacenter": "workspace:*",
|
||||||
|
"@affine/debug": "workspace:*",
|
||||||
"@blocksuite/blocks": "0.4.1",
|
"@blocksuite/blocks": "0.4.1",
|
||||||
"@blocksuite/editor": "0.4.1",
|
"@blocksuite/editor": "0.4.1",
|
||||||
"@blocksuite/global": "0.4.1",
|
"@blocksuite/global": "0.4.1",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { User } from '@affine/datacenter';
|
import { User } from '@affine/datacenter';
|
||||||
|
import { DebugLogger } from '@affine/debug';
|
||||||
|
|
||||||
import { GlobalActionsCreator } from '..';
|
import { GlobalActionsCreator } from '..';
|
||||||
import { dataCenterPromise } from '../datacenter';
|
import { dataCenterPromise } from '../datacenter';
|
||||||
@@ -19,6 +20,8 @@ export const createUserState = (): UserState => ({
|
|||||||
isOwner: false,
|
isOwner: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const logger = new DebugLogger('store:user');
|
||||||
|
|
||||||
export const createUserActions: GlobalActionsCreator<UserActions> = (
|
export const createUserActions: GlobalActionsCreator<UserActions> = (
|
||||||
set,
|
set,
|
||||||
get
|
get
|
||||||
@@ -45,14 +48,19 @@ export const createUserActions: GlobalActionsCreator<UserActions> = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
set({ user, isOwner });
|
set({ user, isOwner });
|
||||||
|
|
||||||
|
logger.debug('login success', user);
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
logger.error('login failed', error);
|
||||||
return null; // login failed
|
return null; // login failed
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
logout: async () => {
|
logout: async () => {
|
||||||
const dataCenter = await dataCenterPromise;
|
const dataCenter = await dataCenterPromise;
|
||||||
await dataCenter.logout();
|
await dataCenter.logout();
|
||||||
|
logger.debug('logout success');
|
||||||
set({ user: null });
|
set({ user: null });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
26
pnpm-lock.yaml
generated
26
pnpm-lock.yaml
generated
@@ -145,6 +145,7 @@ importers:
|
|||||||
specifiers:
|
specifiers:
|
||||||
'@affine/component': workspace:*
|
'@affine/component': workspace:*
|
||||||
'@affine/datacenter': workspace:*
|
'@affine/datacenter': workspace:*
|
||||||
|
'@affine/debug': workspace:*
|
||||||
'@affine/i18n': workspace:*
|
'@affine/i18n': workspace:*
|
||||||
'@affine/store': workspace:*
|
'@affine/store': workspace:*
|
||||||
'@blocksuite/blocks': 0.4.1
|
'@blocksuite/blocks': 0.4.1
|
||||||
@@ -188,6 +189,7 @@ importers:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@affine/component': link:../../packages/component
|
'@affine/component': link:../../packages/component
|
||||||
'@affine/datacenter': link:../../packages/data-center
|
'@affine/datacenter': link:../../packages/data-center
|
||||||
|
'@affine/debug': link:../../packages/debug
|
||||||
'@affine/i18n': link:../../packages/i18n
|
'@affine/i18n': link:../../packages/i18n
|
||||||
'@affine/store': link:../../packages/store
|
'@affine/store': link:../../packages/store
|
||||||
'@blocksuite/blocks': 0.4.1_tdlxw56kpoc45go7l7gsdk5hjm
|
'@blocksuite/blocks': 0.4.1_tdlxw56kpoc45go7l7gsdk5hjm
|
||||||
@@ -232,6 +234,7 @@ importers:
|
|||||||
|
|
||||||
packages/component:
|
packages/component:
|
||||||
specifiers:
|
specifiers:
|
||||||
|
'@affine/debug': workspace:*
|
||||||
'@affine/i18n': workspace:*
|
'@affine/i18n': workspace:*
|
||||||
'@blocksuite/blocks': 0.4.1
|
'@blocksuite/blocks': 0.4.1
|
||||||
'@blocksuite/editor': 0.4.1
|
'@blocksuite/editor': 0.4.1
|
||||||
@@ -265,6 +268,7 @@ importers:
|
|||||||
webpack: ^5.75.0
|
webpack: ^5.75.0
|
||||||
yjs: ^13.5.46
|
yjs: ^13.5.46
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@affine/debug': link:../debug
|
||||||
'@affine/i18n': link:../i18n
|
'@affine/i18n': link:../i18n
|
||||||
'@blocksuite/blocks': 0.4.1_tdlxw56kpoc45go7l7gsdk5hjm
|
'@blocksuite/blocks': 0.4.1_tdlxw56kpoc45go7l7gsdk5hjm
|
||||||
'@blocksuite/editor': 0.4.1_e5cdg6aldwc4hxgrfphufwkeea
|
'@blocksuite/editor': 0.4.1_e5cdg6aldwc4hxgrfphufwkeea
|
||||||
@@ -301,11 +305,10 @@ importers:
|
|||||||
|
|
||||||
packages/data-center:
|
packages/data-center:
|
||||||
specifiers:
|
specifiers:
|
||||||
|
'@affine/debug': workspace:*
|
||||||
'@blocksuite/blocks': 0.4.1
|
'@blocksuite/blocks': 0.4.1
|
||||||
'@blocksuite/store': 0.4.1
|
'@blocksuite/store': 0.4.1
|
||||||
'@tauri-apps/api': ^1.2.0
|
'@tauri-apps/api': ^1.2.0
|
||||||
'@types/debug': ^4.1.7
|
|
||||||
debug: ^4.3.4
|
|
||||||
encoding: ^0.1.13
|
encoding: ^0.1.13
|
||||||
fake-indexeddb: 4.0.1
|
fake-indexeddb: 4.0.1
|
||||||
firebase: ^9.17.1
|
firebase: ^9.17.1
|
||||||
@@ -319,10 +322,10 @@ importers:
|
|||||||
y-protocols: ^1.0.5
|
y-protocols: ^1.0.5
|
||||||
yjs: ^13.5.46
|
yjs: ^13.5.46
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@affine/debug': link:../debug
|
||||||
'@blocksuite/blocks': 0.4.1_tdlxw56kpoc45go7l7gsdk5hjm
|
'@blocksuite/blocks': 0.4.1_tdlxw56kpoc45go7l7gsdk5hjm
|
||||||
'@blocksuite/store': 0.4.1_lit@2.6.1+yjs@13.5.46
|
'@blocksuite/store': 0.4.1_lit@2.6.1+yjs@13.5.46
|
||||||
'@tauri-apps/api': 1.2.0_nb4isgkwd3sres4g7j7rgtldsu
|
'@tauri-apps/api': 1.2.0_nb4isgkwd3sres4g7j7rgtldsu
|
||||||
debug: 4.3.4
|
|
||||||
encoding: 0.1.13
|
encoding: 0.1.13
|
||||||
firebase: 9.17.1_encoding@0.1.13
|
firebase: 9.17.1_encoding@0.1.13
|
||||||
idb-keyval: 6.2.0
|
idb-keyval: 6.2.0
|
||||||
@@ -334,12 +337,20 @@ importers:
|
|||||||
y-protocols: 1.0.5
|
y-protocols: 1.0.5
|
||||||
yjs: 13.5.46
|
yjs: 13.5.46
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/debug': 4.1.7
|
|
||||||
fake-indexeddb: 4.0.1
|
fake-indexeddb: 4.0.1
|
||||||
typescript: 4.9.5
|
typescript: 4.9.5
|
||||||
|
|
||||||
|
packages/debug:
|
||||||
|
specifiers:
|
||||||
|
'@types/debug': ^4.1.7
|
||||||
|
debug: ^4.3.4
|
||||||
|
dependencies:
|
||||||
|
'@types/debug': 4.1.7
|
||||||
|
debug: 4.3.4
|
||||||
|
|
||||||
packages/i18n:
|
packages/i18n:
|
||||||
specifiers:
|
specifiers:
|
||||||
|
'@affine/debug': workspace:*
|
||||||
'@types/node': ^18.14.0
|
'@types/node': ^18.14.0
|
||||||
'@types/prettier': ^2.7.2
|
'@types/prettier': ^2.7.2
|
||||||
i18next: ^22.4.10
|
i18next: ^22.4.10
|
||||||
@@ -349,6 +360,7 @@ importers:
|
|||||||
ts-node: ^10.9.1
|
ts-node: ^10.9.1
|
||||||
typescript: ^4.9.5
|
typescript: ^4.9.5
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@affine/debug': link:../debug
|
||||||
i18next: 22.4.10
|
i18next: 22.4.10
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
react-i18next: 12.1.5_dxv7ampvtjrtnimevxnrn5rvga
|
react-i18next: 12.1.5_dxv7ampvtjrtnimevxnrn5rvga
|
||||||
@@ -377,6 +389,7 @@ importers:
|
|||||||
packages/store:
|
packages/store:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@affine/datacenter': workspace:*
|
'@affine/datacenter': workspace:*
|
||||||
|
'@affine/debug': workspace:*
|
||||||
'@blocksuite/blocks': 0.4.1
|
'@blocksuite/blocks': 0.4.1
|
||||||
'@blocksuite/editor': 0.4.1
|
'@blocksuite/editor': 0.4.1
|
||||||
'@blocksuite/global': 0.4.1
|
'@blocksuite/global': 0.4.1
|
||||||
@@ -392,6 +405,7 @@ importers:
|
|||||||
zustand: ^4.3.3
|
zustand: ^4.3.3
|
||||||
dependencies:
|
dependencies:
|
||||||
'@affine/datacenter': link:../data-center
|
'@affine/datacenter': link:../data-center
|
||||||
|
'@affine/debug': link:../debug
|
||||||
'@blocksuite/blocks': 0.4.1_tdlxw56kpoc45go7l7gsdk5hjm
|
'@blocksuite/blocks': 0.4.1_tdlxw56kpoc45go7l7gsdk5hjm
|
||||||
'@blocksuite/editor': 0.4.1_e5cdg6aldwc4hxgrfphufwkeea
|
'@blocksuite/editor': 0.4.1_e5cdg6aldwc4hxgrfphufwkeea
|
||||||
'@blocksuite/global': 0.4.1_lit@2.6.1
|
'@blocksuite/global': 0.4.1_lit@2.6.1
|
||||||
@@ -6157,7 +6171,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==}
|
resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/ms': 0.7.31
|
'@types/ms': 0.7.31
|
||||||
dev: true
|
dev: false
|
||||||
|
|
||||||
/@types/detect-port/1.3.2:
|
/@types/detect-port/1.3.2:
|
||||||
resolution: {integrity: sha512-xxgAGA2SAU4111QefXPSp5eGbDm/hW6zhvYl9IeEPZEry9F4d66QAHm5qpUXjb6IsevZV/7emAEx5MhP6O192g==}
|
resolution: {integrity: sha512-xxgAGA2SAU4111QefXPSp5eGbDm/hW6zhvYl9IeEPZEry9F4d66QAHm5qpUXjb6IsevZV/7emAEx5MhP6O192g==}
|
||||||
@@ -6314,7 +6328,7 @@ packages:
|
|||||||
|
|
||||||
/@types/ms/0.7.31:
|
/@types/ms/0.7.31:
|
||||||
resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
|
resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
|
||||||
dev: true
|
dev: false
|
||||||
|
|
||||||
/@types/node-fetch/2.6.2:
|
/@types/node-fetch/2.6.2:
|
||||||
resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==}
|
resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
"@affine/datacenter": ["./packages/datacenter/src"],
|
"@affine/datacenter": ["./packages/datacenter/src"],
|
||||||
"@affine/i18n": ["./packages/i18n/src"],
|
"@affine/i18n": ["./packages/i18n/src"],
|
||||||
"@affine/logger": ["./packages/logger/src"],
|
"@affine/logger": ["./packages/logger/src"],
|
||||||
"@affine/store": ["packages/store/src"],
|
"@affine/store": ["./packages/store/src"],
|
||||||
|
"@affine/debug": ["./packages/store/debug"],
|
||||||
"@toeverything/pathfinder-logger": ["./packages/logger"]
|
"@toeverything/pathfinder-logger": ["./packages/logger"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user