fix(core): circular dependencies (#8215)

This commit is contained in:
forehalo 2024-09-13 09:03:23 +00:00
parent a387e4ac07
commit 2ce9d37af1
No known key found for this signature in database
GPG Key ID: 56709255DC7EC728
7 changed files with 90 additions and 66 deletions

View File

@ -35,6 +35,7 @@ import { SubscriptionPrices } from './entities/subscription-prices';
import { UserCopilotQuota } from './entities/user-copilot-quota'; import { UserCopilotQuota } from './entities/user-copilot-quota';
import { UserFeature } from './entities/user-feature'; import { UserFeature } from './entities/user-feature';
import { UserQuota } from './entities/user-quota'; import { UserQuota } from './entities/user-quota';
import { AIService } from './services/ai';
import { AuthService } from './services/auth'; import { AuthService } from './services/auth';
import { CloudDocMetaService } from './services/cloud-doc-meta'; import { CloudDocMetaService } from './services/cloud-doc-meta';
import { FetchService } from './services/fetch'; import { FetchService } from './services/fetch';
@ -68,6 +69,7 @@ export function configureCloudModule(framework: Framework) {
.entity(AuthSession, [AuthStore]) .entity(AuthSession, [AuthStore])
.service(SubscriptionService, [SubscriptionStore]) .service(SubscriptionService, [SubscriptionStore])
.store(SubscriptionStore, [GraphQLService, GlobalCache]) .store(SubscriptionStore, [GraphQLService, GlobalCache])
.service(AIService, [AuthService])
.entity(Subscription, [AuthService, ServerConfigService, SubscriptionStore]) .entity(Subscription, [AuthService, ServerConfigService, SubscriptionStore])
.entity(SubscriptionPrices, [ServerConfigService, SubscriptionStore]) .entity(SubscriptionPrices, [ServerConfigService, SubscriptionStore])
.service(UserQuotaService) .service(UserQuotaService)

View File

@ -0,0 +1,38 @@
import { AIProvider } from '@affine/core/blocksuite/presets/ai';
import { Service } from '@toeverything/infra';
import { distinctUntilChanged, map, skip } from 'rxjs';
import { type AuthAccountInfo } from '../entities/session';
import type { AuthService } from './auth';
function toAIUserInfo(account: AuthAccountInfo | null) {
if (!account) return null;
return {
avatarUrl: account.avatar ?? '',
email: account.email ?? '',
id: account.id,
name: account.label,
};
}
export class AIService extends Service {
constructor(private readonly auth: AuthService) {
super();
AIProvider.provide('userInfo', () => {
return toAIUserInfo(this.auth.session.account$.value);
});
this.auth.session.account$
.pipe(
map(a => ({
id: a?.id,
account: a,
})),
distinctUntilChanged((a, b) => a.id === b.id), // only emit when the value changes
skip(1) // skip the initial value
)
.subscribe(({ account }) => {
AIProvider.slots.userInfo.emit(toAIUserInfo(account));
});
}
}

View File

@ -1,4 +1,3 @@
import { AIProvider } from '@affine/core/blocksuite/presets/ai';
import { track } from '@affine/core/mixpanel'; import { track } from '@affine/core/mixpanel';
import { appInfo } from '@affine/electron-api'; import { appInfo } from '@affine/electron-api';
import type { OAuthProviderType } from '@affine/graphql'; import type { OAuthProviderType } from '@affine/graphql';
@ -25,16 +24,6 @@ export const AccountLoggedIn = createEvent<AuthAccountInfo>('AccountLoggedIn');
export const AccountLoggedOut = export const AccountLoggedOut =
createEvent<AuthAccountInfo>('AccountLoggedOut'); createEvent<AuthAccountInfo>('AccountLoggedOut');
function toAIUserInfo(account: AuthAccountInfo | null) {
if (!account) return null;
return {
avatarUrl: account.avatar ?? '',
email: account.email ?? '',
id: account.id,
name: account.label,
};
}
@OnEvent(ApplicationStarted, e => e.onApplicationStart) @OnEvent(ApplicationStarted, e => e.onApplicationStart)
@OnEvent(ApplicationFocused, e => e.onApplicationFocused) @OnEvent(ApplicationFocused, e => e.onApplicationFocused)
export class AuthService extends Service { export class AuthService extends Service {
@ -46,10 +35,6 @@ export class AuthService extends Service {
) { ) {
super(); super();
AIProvider.provide('userInfo', () => {
return toAIUserInfo(this.session.account$.value);
});
this.session.account$ this.session.account$
.pipe( .pipe(
map(a => ({ map(a => ({
@ -66,7 +51,6 @@ export class AuthService extends Service {
this.eventBus.emit(AccountLoggedIn, account); this.eventBus.emit(AccountLoggedIn, account);
} }
this.eventBus.emit(AccountChanged, account); this.eventBus.emit(AccountChanged, account);
AIProvider.slots.userInfo.emit(toAIUserInfo(account));
}); });
} }

View File

@ -1,6 +1,6 @@
import { ResizePanel } from '@affine/component/resize-panel'; import { ResizePanel } from '@affine/component/resize-panel';
import { rightSidebarWidthAtom } from '@affine/core/atoms'; import { rightSidebarWidthAtom } from '@affine/core/atoms';
import { viewRoutes } from '@affine/core/router'; import { workspaceRoutes } from '@affine/core/workspace-router';
import { import {
appSettingAtom, appSettingAtom,
FrameworkScope, FrameworkScope,
@ -8,7 +8,7 @@ import {
useService, useService,
} from '@toeverything/infra'; } from '@toeverything/infra';
import { useAtom, useAtomValue } from 'jotai'; import { useAtom, useAtomValue } from 'jotai';
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { memo, useCallback, useEffect, useRef, useState } from 'react';
import { type RouteObject, useLocation } from 'react-router-dom'; import { type RouteObject, useLocation } from 'react-router-dom';
import type { View } from '../entities/view'; import type { View } from '../entities/view';
@ -26,6 +26,13 @@ const useAdapter = BUILD_CONFIG.isElectron
? useBindWorkbenchToDesktopRouter ? useBindWorkbenchToDesktopRouter
: useBindWorkbenchToBrowserRouter; : useBindWorkbenchToBrowserRouter;
const routes: RouteObject[] = [
{
element: <RouteContainer />,
children: workspaceRoutes,
},
];
export const WorkbenchRoot = memo(() => { export const WorkbenchRoot = memo(() => {
const workbench = useService(WorkbenchService).workbench; const workbench = useService(WorkbenchService).workbench;
@ -93,15 +100,6 @@ const WorkbenchView = ({ view, index }: { view: View; index: number }) => {
return; return;
}, [handleOnFocus]); }, [handleOnFocus]);
const routes: RouteObject[] = useMemo(() => {
return [
{
element: <RouteContainer />,
children: viewRoutes,
},
] satisfies RouteObject[];
}, []);
return ( return (
<div className={styles.workbenchViewContainer} ref={containerRef}> <div className={styles.workbenchViewContainer} ref={containerRef}>
<ViewRoot routes={routes} key={view.id} view={view} /> <ViewRoot routes={routes} key={view.id} view={view} />

View File

@ -1,6 +1,6 @@
import { AffineOtherPageLayout } from '@affine/component/affine-other-page-layout'; import { AffineOtherPageLayout } from '@affine/component/affine-other-page-layout';
import { AppFallback } from '@affine/core/components/affine/app-container'; import { AppFallback } from '@affine/core/components/affine/app-container';
import { viewRoutes } from '@affine/core/router'; import { workspaceRoutes } from '@affine/core/workspace-router';
import { ZipTransformer } from '@blocksuite/blocks'; import { ZipTransformer } from '@blocksuite/blocks';
import type { Workspace, WorkspaceMetadata } from '@toeverything/infra'; import type { Workspace, WorkspaceMetadata } from '@toeverything/infra';
import { import {
@ -55,9 +55,10 @@ export const Component = (): ReactElement => {
match && match &&
match.params.docId && match.params.docId &&
match.params.workspaceId && match.params.workspaceId &&
// TODO(eyhn): need a better way to check if it's a docId // // TODO(eyhn): need a better way to check if it's a docId
viewRoutes.find(route => matchPath(route.path, '/' + match.params.docId)) workspaceRoutes.find(route =>
?.path === '/:pageId' matchPath(route.path, '/' + match.params.docId)
)?.path === '/:pageId'
) { ) {
return { return {
docId: match.params.docId, docId: match.params.docId,

View File

@ -163,41 +163,6 @@ export const topLevelRoutes = [
}, },
] satisfies [RouteObject, ...RouteObject[]]; ] satisfies [RouteObject, ...RouteObject[]];
export const viewRoutes = [
{
path: '/all',
lazy: () => import('./pages/workspace/all-page/all-page'),
},
{
path: '/collection',
lazy: () => import('./pages/workspace/all-collection'),
},
{
path: '/collection/:collectionId',
lazy: () => import('./pages/workspace/collection/index'),
},
{
path: '/tag',
lazy: () => import('./pages/workspace/all-tag'),
},
{
path: '/tag/:tagId',
lazy: () => import('./pages/workspace/tag'),
},
{
path: '/trash',
lazy: () => import('./pages/workspace/trash-page'),
},
{
path: '/:pageId',
lazy: () => import('./pages/workspace/detail-page/detail-page'),
},
{
path: '*',
lazy: () => import('./pages/404'),
},
] satisfies [RouteObject, ...RouteObject[]];
const createBrowserRouter = wrapCreateBrowserRouter( const createBrowserRouter = wrapCreateBrowserRouter(
reactRouterCreateBrowserRouter reactRouterCreateBrowserRouter
); );

View File

@ -0,0 +1,36 @@
import type { RouteObject } from 'react-router-dom';
export const workspaceRoutes = [
{
path: '/all',
lazy: () => import('./pages/workspace/all-page/all-page'),
},
{
path: '/collection',
lazy: () => import('./pages/workspace/all-collection'),
},
{
path: '/collection/:collectionId',
lazy: () => import('./pages/workspace/collection/index'),
},
{
path: '/tag',
lazy: () => import('./pages/workspace/all-tag'),
},
{
path: '/tag/:tagId',
lazy: () => import('./pages/workspace/tag'),
},
{
path: '/trash',
lazy: () => import('./pages/workspace/trash-page'),
},
{
path: '/:pageId',
lazy: () => import('./pages/workspace/detail-page/detail-page'),
},
{
path: '*',
lazy: () => import('./pages/404'),
},
] satisfies RouteObject[];