mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-19 19:16:29 +08:00
feat(core): support better battery save mode (#13383)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced a Document Summary module, enabling live and cached document summaries with cloud revalidation. * Added a feature flag for enabling battery save mode. * Added explicit pause and resume controls for sync operations, accessible via UI events and programmatically. * **Improvements** * Enhanced sync and indexing logic to support pausing, resuming, and battery save mode, with improved job prioritization. * Updated navigation and preview components to use the new document summary service and improved priority handling. * Improved logging and state reporting for sync and indexing processes. * Refined backlink handling with reactive loading states and cloud revalidation. * Replaced backlink and link management to use a new dedicated document links service. * Enhanced workspace engine to conditionally enable battery save mode based on feature flags and workspace flavor. * **Bug Fixes** * Removed unnecessary debug console logs from various components for cleaner output. * **Refactor** * Replaced battery save mode methods with explicit pause/resume methods throughout the app and services. * Modularized and streamlined document summary and sync-related code for better maintainability. * Restructured backlink components to improve visibility handling and data fetching. * Simplified and improved document backlink data fetching with retry and loading state management. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,7 +1,20 @@
|
||||
import { Entity, LiveData } from '@toeverything/infra';
|
||||
import {
|
||||
catchErrorInto,
|
||||
effect,
|
||||
Entity,
|
||||
exhaustMapWithTrailing,
|
||||
fromPromise,
|
||||
LiveData,
|
||||
onComplete,
|
||||
onStart,
|
||||
smartRetry,
|
||||
} from '@toeverything/infra';
|
||||
import { tap } from 'rxjs';
|
||||
|
||||
import type { DocService } from '../../doc';
|
||||
import type { DocService, DocsService } from '../../doc';
|
||||
import type { DocsSearchService } from '../../docs-search';
|
||||
import type { FeatureFlagService } from '../../feature-flag';
|
||||
import type { WorkspaceService } from '../../workspace';
|
||||
|
||||
export interface Backlink {
|
||||
docId: string;
|
||||
@@ -17,13 +30,128 @@ export interface Backlink {
|
||||
export class DocBacklinks extends Entity {
|
||||
constructor(
|
||||
private readonly docsSearchService: DocsSearchService,
|
||||
private readonly docService: DocService
|
||||
private readonly docService: DocService,
|
||||
private readonly docsService: DocsService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
private readonly workspaceService: WorkspaceService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
backlinks$ = LiveData.from<Backlink[]>(
|
||||
this.docsSearchService.watchRefsTo(this.docService.doc.id),
|
||||
[]
|
||||
backlinks$ = new LiveData<Backlink[] | undefined>(undefined);
|
||||
|
||||
isLoading$ = new LiveData<boolean>(false);
|
||||
error$ = new LiveData<any>(undefined);
|
||||
|
||||
revalidateFromCloud = effect(
|
||||
exhaustMapWithTrailing(() =>
|
||||
fromPromise(async () => {
|
||||
const searchFromCloud =
|
||||
this.featureFlagService.flags.enable_battery_save_mode &&
|
||||
this.workspaceService.workspace.flavour !== 'local';
|
||||
const { buckets } = await this.docsSearchService.indexer.aggregate(
|
||||
'block',
|
||||
{
|
||||
type: 'boolean',
|
||||
occur: 'must',
|
||||
queries: [
|
||||
{
|
||||
type: 'match',
|
||||
field: 'refDocId',
|
||||
match: this.docService.doc.id,
|
||||
},
|
||||
],
|
||||
},
|
||||
'docId',
|
||||
{
|
||||
hits: {
|
||||
fields: [
|
||||
'docId',
|
||||
'blockId',
|
||||
'parentBlockId',
|
||||
'parentFlavour',
|
||||
'additional',
|
||||
'markdownPreview',
|
||||
],
|
||||
pagination: {
|
||||
limit: 5, // the max number of backlinks to show for each doc
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
limit: 100,
|
||||
},
|
||||
prefer: searchFromCloud ? 'remote' : 'local',
|
||||
}
|
||||
);
|
||||
return buckets.flatMap(bucket => {
|
||||
const title =
|
||||
this.docsService.list.doc$(bucket.key).value?.title$.value ?? '';
|
||||
|
||||
if (bucket.key === this.docService.doc.id) {
|
||||
// Ignore if it is a link to the current document.
|
||||
return [];
|
||||
}
|
||||
|
||||
return bucket.hits.nodes.map(node => {
|
||||
const blockId = node.fields.blockId ?? '';
|
||||
const markdownPreview = node.fields.markdownPreview ?? '';
|
||||
const additional =
|
||||
typeof node.fields.additional === 'string'
|
||||
? node.fields.additional
|
||||
: node.fields.additional[0];
|
||||
|
||||
const additionalData: {
|
||||
displayMode?: string;
|
||||
noteBlockId?: string;
|
||||
} = JSON.parse(additional || '{}');
|
||||
|
||||
const displayMode = additionalData.displayMode ?? '';
|
||||
const noteBlockId = additionalData.noteBlockId ?? '';
|
||||
const parentBlockId =
|
||||
typeof node.fields.parentBlockId === 'string'
|
||||
? node.fields.parentBlockId
|
||||
: node.fields.parentBlockId[0];
|
||||
const parentFlavour =
|
||||
typeof node.fields.parentFlavour === 'string'
|
||||
? node.fields.parentFlavour
|
||||
: node.fields.parentFlavour[0];
|
||||
|
||||
return {
|
||||
docId: bucket.key,
|
||||
blockId: typeof blockId === 'string' ? blockId : blockId[0],
|
||||
title: title,
|
||||
markdownPreview:
|
||||
typeof markdownPreview === 'string'
|
||||
? markdownPreview
|
||||
: markdownPreview[0],
|
||||
displayMode:
|
||||
typeof displayMode === 'string' ? displayMode : displayMode[0],
|
||||
noteBlockId:
|
||||
typeof noteBlockId === 'string' ? noteBlockId : noteBlockId[0],
|
||||
parentBlockId:
|
||||
typeof parentBlockId === 'string'
|
||||
? parentBlockId
|
||||
: parentBlockId[0],
|
||||
parentFlavour:
|
||||
typeof parentFlavour === 'string'
|
||||
? parentFlavour
|
||||
: parentFlavour[0],
|
||||
};
|
||||
});
|
||||
});
|
||||
}).pipe(
|
||||
smartRetry(),
|
||||
tap(backlinks => {
|
||||
this.backlinks$.value = backlinks;
|
||||
}),
|
||||
catchErrorInto(this.error$),
|
||||
onStart(() => {
|
||||
this.isLoading$.value = true;
|
||||
}),
|
||||
onComplete(() => {
|
||||
this.isLoading$.value = false;
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,10 @@ import { type Framework } from '@toeverything/infra';
|
||||
|
||||
import { DocScope } from '../doc/scopes/doc';
|
||||
import { DocService } from '../doc/services/doc';
|
||||
import { DocsService } from '../doc/services/docs';
|
||||
import { DocsSearchService } from '../docs-search';
|
||||
import { WorkspaceScope } from '../workspace';
|
||||
import { FeatureFlagService } from '../feature-flag';
|
||||
import { WorkspaceScope, WorkspaceService } from '../workspace';
|
||||
import { DocBacklinks } from './entities/doc-backlinks';
|
||||
import { DocLinks } from './entities/doc-links';
|
||||
import { DocLinksService } from './services/doc-links';
|
||||
@@ -17,6 +19,12 @@ export function configureDocLinksModule(framework: Framework) {
|
||||
.scope(WorkspaceScope)
|
||||
.scope(DocScope)
|
||||
.service(DocLinksService)
|
||||
.entity(DocBacklinks, [DocsSearchService, DocService])
|
||||
.entity(DocBacklinks, [
|
||||
DocsSearchService,
|
||||
DocService,
|
||||
DocsService,
|
||||
FeatureFlagService,
|
||||
WorkspaceService,
|
||||
])
|
||||
.entity(DocLinks, [DocsSearchService, DocService]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { Framework } from '@toeverything/infra';
|
||||
|
||||
import { WorkspaceServerService } from '../cloud';
|
||||
import { FeatureFlagService } from '../feature-flag';
|
||||
import { CacheStorage } from '../storage';
|
||||
import { WorkspaceScope, WorkspaceService } from '../workspace';
|
||||
import { DocSummaryService } from './services/doc-summary';
|
||||
import { DocSummaryStore } from './stores/doc-summary';
|
||||
|
||||
export { DocSummaryService };
|
||||
|
||||
export function configureDocSummaryModule(framework: Framework) {
|
||||
framework
|
||||
.scope(WorkspaceScope)
|
||||
.service(DocSummaryService, [
|
||||
WorkspaceService,
|
||||
DocSummaryStore,
|
||||
FeatureFlagService,
|
||||
])
|
||||
.store(DocSummaryStore, [
|
||||
WorkspaceService,
|
||||
WorkspaceServerService,
|
||||
CacheStorage,
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import { effect, fromPromise, Service, smartRetry } from '@toeverything/infra';
|
||||
import { catchError, EMPTY, Observable, type Subscription, tap } from 'rxjs';
|
||||
|
||||
import type { FeatureFlagService } from '../../feature-flag';
|
||||
import type { WorkspaceService } from '../../workspace';
|
||||
import type { DocSummaryStore } from '../stores/doc-summary';
|
||||
|
||||
export class DocSummaryService extends Service {
|
||||
constructor(
|
||||
private readonly workspaceService: WorkspaceService,
|
||||
private readonly store: DocSummaryStore,
|
||||
private readonly featureFlagService: FeatureFlagService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
private readonly docSummaryCache = new Map<
|
||||
string,
|
||||
Observable<string | undefined>
|
||||
>();
|
||||
|
||||
watchDocSummary(docId: string) {
|
||||
const cached$ = this.docSummaryCache.get(docId);
|
||||
if (!cached$) {
|
||||
const ob$ = new Observable<string | undefined>(subscribe => {
|
||||
if (
|
||||
this.workspaceService.workspace.flavour === 'local' ||
|
||||
this.featureFlagService.flags.enable_battery_save_mode.value === false
|
||||
) {
|
||||
// use local indexer
|
||||
const sub = this.store
|
||||
.watchDocSummaryFromIndexer(docId)
|
||||
.subscribe(subscribe);
|
||||
return () => sub.unsubscribe();
|
||||
}
|
||||
// use cache, and revalidate from cloud
|
||||
const sub = this.store.watchDocSummaryCache(docId).subscribe(subscribe);
|
||||
this.revalidateDocSummaryFromCloud(docId);
|
||||
return () => sub.unsubscribe();
|
||||
});
|
||||
this.docSummaryCache.set(docId, ob$);
|
||||
return ob$;
|
||||
}
|
||||
return cached$;
|
||||
}
|
||||
|
||||
private readonly revalidateDocSummaryFromCloud = effect(
|
||||
(source$: Observable<string>) => {
|
||||
// make a lifo queue
|
||||
const queue: string[] = [];
|
||||
|
||||
let currentTask: Subscription | undefined;
|
||||
|
||||
const processTask = () => {
|
||||
if (currentTask) {
|
||||
return;
|
||||
}
|
||||
const docId = queue.pop();
|
||||
if (!docId) {
|
||||
return;
|
||||
}
|
||||
currentTask = fromPromise(this.store.getDocSummaryFromCloud(docId))
|
||||
.pipe(
|
||||
smartRetry(),
|
||||
tap(summary => {
|
||||
if (summary) {
|
||||
this.store.setDocSummaryCache(docId, summary).catch(error => {
|
||||
console.error(error);
|
||||
// ignore error
|
||||
});
|
||||
}
|
||||
}),
|
||||
catchError(error => {
|
||||
console.error(error);
|
||||
// ignore error
|
||||
return EMPTY;
|
||||
})
|
||||
)
|
||||
.subscribe({
|
||||
complete() {
|
||||
currentTask = undefined;
|
||||
processTask();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return new Observable(subscriber => {
|
||||
const sub = source$.subscribe({
|
||||
next: value => {
|
||||
queue.push(value);
|
||||
processTask();
|
||||
},
|
||||
complete: () => {
|
||||
subscriber.complete();
|
||||
},
|
||||
});
|
||||
return () => {
|
||||
sub.unsubscribe();
|
||||
currentTask?.unsubscribe();
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
override dispose() {
|
||||
this.revalidateDocSummaryFromCloud.unsubscribe();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { getDocSummaryQuery } from '@affine/graphql';
|
||||
import { Store } from '@toeverything/infra';
|
||||
import { map, Observable } from 'rxjs';
|
||||
|
||||
import type { WorkspaceServerService } from '../../cloud';
|
||||
import type { CacheStorage } from '../../storage';
|
||||
import type { WorkspaceService } from '../../workspace';
|
||||
|
||||
export class DocSummaryStore extends Store {
|
||||
get indexer() {
|
||||
return this.workspaceService.workspace.engine.indexer;
|
||||
}
|
||||
|
||||
private readonly gql = this.workspaceServerService.server?.gql;
|
||||
|
||||
constructor(
|
||||
private readonly workspaceService: WorkspaceService,
|
||||
private readonly workspaceServerService: WorkspaceServerService,
|
||||
private readonly cacheStorage: CacheStorage
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async getDocSummaryFromCloud(docId: string) {
|
||||
return this.gql?.({
|
||||
query: getDocSummaryQuery,
|
||||
variables: {
|
||||
workspaceId: this.workspaceService.workspace.id,
|
||||
docId,
|
||||
},
|
||||
}).then(res => res.workspace.doc.summary ?? '');
|
||||
}
|
||||
|
||||
watchDocSummaryFromIndexer(docId: string) {
|
||||
return new Observable<string>(subscribe => {
|
||||
const undoIndexer = this.indexer.addPriority(docId, 10);
|
||||
const undoSync = this.workspaceService.workspace.engine.doc.addPriority(
|
||||
docId,
|
||||
10
|
||||
);
|
||||
const sub = this.indexer
|
||||
.search$(
|
||||
'doc',
|
||||
{
|
||||
type: 'match',
|
||||
field: 'docId',
|
||||
match: docId,
|
||||
},
|
||||
{
|
||||
fields: ['summary'],
|
||||
pagination: {
|
||||
limit: 1,
|
||||
},
|
||||
}
|
||||
)
|
||||
.pipe(
|
||||
map(({ nodes }) => {
|
||||
const node = nodes.at(0);
|
||||
return (
|
||||
(typeof node?.fields.summary === 'string'
|
||||
? node?.fields.summary
|
||||
: node?.fields.summary[0]) ?? ''
|
||||
);
|
||||
})
|
||||
)
|
||||
.subscribe(subscribe);
|
||||
return () => {
|
||||
undoIndexer();
|
||||
undoSync();
|
||||
sub.unsubscribe();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async setDocSummaryCache(docId: string, summary: string) {
|
||||
return this.cacheStorage.set(
|
||||
`doc-summary:${this.workspaceService.workspace.id}:${docId}`,
|
||||
summary
|
||||
);
|
||||
}
|
||||
|
||||
watchDocSummaryCache(docId: string) {
|
||||
return this.cacheStorage.watch<string>(
|
||||
`doc-summary:${this.workspaceService.workspace.id}:${docId}`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,14 @@ export class Doc extends Entity {
|
||||
this.yDoc.off('afterTransaction', handleTransactionThrottled);
|
||||
handleTransactionThrottled.cancel();
|
||||
});
|
||||
|
||||
this.disposables.push(
|
||||
this.workspaceService.workspace.engine.doc.addPriority(this.id, 100)
|
||||
);
|
||||
|
||||
this.disposables.push(
|
||||
this.workspaceService.workspace.engine.indexer.addPriority(this.id, 100)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,4 +4,9 @@ import { Doc } from '../entities/doc';
|
||||
|
||||
export class DocService extends Service {
|
||||
public readonly doc = this.framework.createEntity(Doc);
|
||||
|
||||
override dispose() {
|
||||
this.doc.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,110 +228,6 @@ export class DocsSearchService extends Service {
|
||||
);
|
||||
}
|
||||
|
||||
watchRefsTo(docId: string) {
|
||||
return this.indexer
|
||||
.aggregate$(
|
||||
'block',
|
||||
{
|
||||
type: 'boolean',
|
||||
occur: 'must',
|
||||
queries: [
|
||||
{
|
||||
type: 'match',
|
||||
field: 'refDocId',
|
||||
match: docId,
|
||||
},
|
||||
],
|
||||
},
|
||||
'docId',
|
||||
{
|
||||
hits: {
|
||||
fields: [
|
||||
'docId',
|
||||
'blockId',
|
||||
'parentBlockId',
|
||||
'parentFlavour',
|
||||
'additional',
|
||||
'markdownPreview',
|
||||
],
|
||||
pagination: {
|
||||
limit: 5, // the max number of backlinks to show for each doc
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
limit: 100,
|
||||
},
|
||||
}
|
||||
)
|
||||
.pipe(
|
||||
switchMap(({ buckets }) => {
|
||||
return fromPromise(async () => {
|
||||
return buckets.flatMap(bucket => {
|
||||
const title =
|
||||
this.docsService.list.doc$(bucket.key).value?.title$.value ??
|
||||
'';
|
||||
|
||||
if (bucket.key === docId) {
|
||||
// Ignore if it is a link to the current document.
|
||||
return [];
|
||||
}
|
||||
|
||||
return bucket.hits.nodes.map(node => {
|
||||
const blockId = node.fields.blockId ?? '';
|
||||
const markdownPreview = node.fields.markdownPreview ?? '';
|
||||
const additional =
|
||||
typeof node.fields.additional === 'string'
|
||||
? node.fields.additional
|
||||
: node.fields.additional[0];
|
||||
|
||||
const additionalData: {
|
||||
displayMode?: string;
|
||||
noteBlockId?: string;
|
||||
} = JSON.parse(additional || '{}');
|
||||
|
||||
const displayMode = additionalData.displayMode ?? '';
|
||||
const noteBlockId = additionalData.noteBlockId ?? '';
|
||||
const parentBlockId =
|
||||
typeof node.fields.parentBlockId === 'string'
|
||||
? node.fields.parentBlockId
|
||||
: node.fields.parentBlockId[0];
|
||||
const parentFlavour =
|
||||
typeof node.fields.parentFlavour === 'string'
|
||||
? node.fields.parentFlavour
|
||||
: node.fields.parentFlavour[0];
|
||||
|
||||
return {
|
||||
docId: bucket.key,
|
||||
blockId: typeof blockId === 'string' ? blockId : blockId[0],
|
||||
title: title,
|
||||
markdownPreview:
|
||||
typeof markdownPreview === 'string'
|
||||
? markdownPreview
|
||||
: markdownPreview[0],
|
||||
displayMode:
|
||||
typeof displayMode === 'string'
|
||||
? displayMode
|
||||
: displayMode[0],
|
||||
noteBlockId:
|
||||
typeof noteBlockId === 'string'
|
||||
? noteBlockId
|
||||
: noteBlockId[0],
|
||||
parentBlockId:
|
||||
typeof parentBlockId === 'string'
|
||||
? parentBlockId
|
||||
: parentBlockId[0],
|
||||
parentFlavour:
|
||||
typeof parentFlavour === 'string'
|
||||
? parentFlavour
|
||||
: parentFlavour[0],
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
watchDatabasesTo(docId: string) {
|
||||
const DatabaseAdditionalSchema = z.object({
|
||||
databaseName: z.string().optional(),
|
||||
|
||||
@@ -281,6 +281,13 @@ export const AFFINE_FLAGS = {
|
||||
configurable: true,
|
||||
defaultState: true,
|
||||
},
|
||||
enable_battery_save_mode: {
|
||||
category: 'affine',
|
||||
displayName: 'Enable Battery Save Mode (Require Restart)',
|
||||
description: 'Enable battery save mode',
|
||||
configurable: isCanaryBuild,
|
||||
defaultState: false,
|
||||
},
|
||||
} satisfies { [key in string]: FlagInfo };
|
||||
|
||||
// oxlint-disable-next-line no-redeclare
|
||||
|
||||
@@ -23,6 +23,7 @@ import { configureDocModule } from './doc';
|
||||
import { configureDocDisplayMetaModule } from './doc-display-meta';
|
||||
import { configureDocInfoModule } from './doc-info';
|
||||
import { configureDocLinksModule } from './doc-link';
|
||||
import { configureDocSummaryModule } from './doc-summary';
|
||||
import { configureDocsSearchModule } from './docs-search';
|
||||
import { configureEditorModule } from './editor';
|
||||
import { configureEditorSettingModule } from './editor-setting';
|
||||
@@ -124,4 +125,5 @@ export function configureCommonModules(framework: Framework) {
|
||||
configureCollectionRulesModule(framework);
|
||||
configureIndexerEmbeddingModule(framework);
|
||||
configureCommentModule(framework);
|
||||
configureDocSummaryModule(framework);
|
||||
}
|
||||
|
||||
@@ -337,8 +337,6 @@ class CloudWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
|
||||
|
||||
const isEmpty = isEmptyUpdate(localData) && isEmptyUpdate(cloudData);
|
||||
|
||||
console.log('isEmpty', isEmpty, localData, cloudData);
|
||||
|
||||
docStorage.connection.disconnect();
|
||||
|
||||
const info = await this.getWorkspaceInfo(id, signal);
|
||||
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
} from '@affine/nbstore/worker/client';
|
||||
import { Entity } from '@toeverything/infra';
|
||||
|
||||
import type { FeatureFlagService } from '../../feature-flag';
|
||||
import type { NbstoreService } from '../../storage';
|
||||
import { WorkspaceEngineBeforeStart } from '../events';
|
||||
import type { WorkspaceService } from '../services/workspace';
|
||||
@@ -17,7 +18,8 @@ export class WorkspaceEngine extends Entity<{
|
||||
|
||||
constructor(
|
||||
private readonly workspaceService: WorkspaceService,
|
||||
private readonly nbstoreService: NbstoreService
|
||||
private readonly nbstoreService: NbstoreService,
|
||||
private readonly featureFlagService: FeatureFlagService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -61,6 +63,14 @@ export class WorkspaceEngine extends Entity<{
|
||||
`workspace:${this.workspaceService.workspace.flavour}:${this.workspaceService.workspace.id}`,
|
||||
this.props.engineWorkerInitOptions
|
||||
);
|
||||
if (
|
||||
this.featureFlagService.flags.enable_battery_save_mode.value &&
|
||||
this.workspaceService.workspace.flavour !== 'local'
|
||||
) {
|
||||
store.enableBatterySaveMode().catch(err => {
|
||||
console.error('error enabling battery save mode', err);
|
||||
});
|
||||
}
|
||||
this.client = store;
|
||||
this.disposables.push(dispose);
|
||||
this.eventBus.emit(WorkspaceEngineBeforeStart, this);
|
||||
@@ -68,6 +78,7 @@ export class WorkspaceEngine extends Entity<{
|
||||
const rootDoc = this.workspaceService.workspace.docCollection.doc;
|
||||
// priority load root doc
|
||||
this.doc.addPriority(rootDoc.guid, 100);
|
||||
this.indexer.addPriority(rootDoc.guid, 100);
|
||||
this.doc.start();
|
||||
this.disposables.push(() => this.doc.stop());
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ export class WorkspaceProfile extends Entity<{ metadata: WorkspaceMetadata }> {
|
||||
}
|
||||
|
||||
private setProfile(info: WorkspaceProfileInfo) {
|
||||
console.log('setProfile', info, isEqual(this.profile$.value, info));
|
||||
if (isEqual(this.profile$.value, info)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,11 @@ export function configureWorkspaceModule(framework: Framework) {
|
||||
.service(WorkspaceService)
|
||||
.entity(Workspace, [WorkspaceScope, FeatureFlagService])
|
||||
.service(WorkspaceEngineService, [WorkspaceScope])
|
||||
.entity(WorkspaceEngine, [WorkspaceService, NbstoreService])
|
||||
.entity(WorkspaceEngine, [
|
||||
WorkspaceService,
|
||||
NbstoreService,
|
||||
FeatureFlagService,
|
||||
])
|
||||
.impl(WorkspaceLocalState, WorkspaceLocalStateImpl, [
|
||||
WorkspaceService,
|
||||
GlobalState,
|
||||
|
||||
Reference in New Issue
Block a user