From b1298c4d3e35b56015538546465f1c4f0ffc54a0 Mon Sep 17 00:00:00 2001 From: Himself65 Date: Sun, 19 Feb 2023 01:35:18 -0600 Subject: [PATCH] refactor(store): move datacenter into global (#1118) --- .../enable-workspace-modal/index.tsx | 3 +- .../enable-workspace-modal/index.tsx | 4 +- .../message-center-handler/index.tsx | 6 +- .../quick-search/PublishedResults.tsx | 5 +- .../src/components/workspace-modal/index.tsx | 4 +- .../WorkspaceSelector/WorkspaceSelector.tsx | 4 +- apps/web/src/hooks/use-ensure-workspace.ts | 4 +- .../src/hooks/use-load-public-workspace.ts | 5 +- apps/web/src/hooks/use-members.ts | 4 +- apps/web/src/hooks/use-workspace-helper.ts | 4 +- apps/web/src/pages/invite/[invite_code].tsx | 4 +- .../workspace/[workspaceId]/[pageId].tsx | 4 +- packages/data-center/src/datacenter.ts | 5 ++ packages/data-center/src/index.ts | 11 --- packages/store/package.json | 1 + packages/store/src/app/datacenter/index.tsx | 73 +++++++++---------- packages/store/src/app/index.tsx | 36 ++++++++- packages/store/src/app/user/index.ts | 6 +- packages/store/src/index.ts | 1 + packages/store/tests/app.spec.tsx | 22 +----- pnpm-lock.yaml | 12 +++ 21 files changed, 120 insertions(+), 98 deletions(-) diff --git a/apps/desktop/src/preload/components/enable-workspace-modal/index.tsx b/apps/desktop/src/preload/components/enable-workspace-modal/index.tsx index b32c1160cc..d75be2511e 100644 --- a/apps/desktop/src/preload/components/enable-workspace-modal/index.tsx +++ b/apps/desktop/src/preload/components/enable-workspace-modal/index.tsx @@ -2,6 +2,7 @@ import { Modal, ModalWrapper } from '@affine/component'; import { IconButton } from '@affine/component'; import { toast } from '@affine/component'; import { useTranslation } from '@affine/i18n'; +import { useDataCenter } from '@affine/store'; import { CloseIcon } from '@blocksuite/icons'; import router from 'next/router'; import { useCallback, useState } from 'react'; @@ -21,7 +22,7 @@ export const EnableWorkspaceModal = ({ const { t } = useTranslation(); const login = useGlobalState(store => store.login); const user = useGlobalState(store => store.user); - const dataCenter = useGlobalState(store => store.dataCenter); + const dataCenter = useDataCenter(); const currentWorkspace = useGlobalState( useCallback(store => store.currentDataCenterWorkspace, []) ); diff --git a/apps/web/src/components/enable-workspace-modal/index.tsx b/apps/web/src/components/enable-workspace-modal/index.tsx index 7d9c696ae1..4b986fc43f 100644 --- a/apps/web/src/components/enable-workspace-modal/index.tsx +++ b/apps/web/src/components/enable-workspace-modal/index.tsx @@ -4,7 +4,7 @@ import { CloseIcon } from '@blocksuite/icons'; import { useRouter } from 'next/router'; import { useCallback, useState } from 'react'; -import { useGlobalState } from '@/store/app'; +import { useDataCenter, useGlobalState } from '@/store/app'; import { Content, ContentTitle, Header, StyleButton, StyleTips } from './style'; @@ -20,7 +20,7 @@ export const EnableWorkspaceModal = ({ const { t } = useTranslation(); const login = useGlobalState(store => store.login); const user = useGlobalState(store => store.user); - const dataCenter = useGlobalState(store => store.dataCenter); + const dataCenter = useDataCenter(); const currentWorkspace = useGlobalState( useCallback(store => store.currentDataCenterWorkspace, []) ); diff --git a/apps/web/src/components/message-center-handler/index.tsx b/apps/web/src/components/message-center-handler/index.tsx index 0339e2d300..e0a3de5724 100644 --- a/apps/web/src/components/message-center-handler/index.tsx +++ b/apps/web/src/components/message-center-handler/index.tsx @@ -2,13 +2,13 @@ import { toast } from '@affine/component'; import { MessageCenter } from '@affine/datacenter'; import { AffineProvider } from '@affine/datacenter'; import { useRouter } from 'next/router'; -import { ReactNode, useCallback, useEffect } from 'react'; +import { ReactNode, useEffect } from 'react'; -import { useGlobalState } from '@/store/app'; +import { useDataCenter } from '@/store/app'; export function MessageCenterHandler({ children }: { children?: ReactNode }) { const router = useRouter(); - const dataCenter = useGlobalState(useCallback(store => store.dataCenter, [])); + const dataCenter = useDataCenter(); useEffect(() => { const instance = MessageCenter.getInstance(); if (instance) { diff --git a/apps/web/src/components/quick-search/PublishedResults.tsx b/apps/web/src/components/quick-search/PublishedResults.tsx index 63c5c23623..45e6e9d2ea 100644 --- a/apps/web/src/components/quick-search/PublishedResults.tsx +++ b/apps/web/src/components/quick-search/PublishedResults.tsx @@ -1,5 +1,5 @@ import { useTranslation } from '@affine/i18n'; -import { PageMeta } from '@affine/store'; +import { PageMeta, useDataCenter } from '@affine/store'; import { EdgelessIcon, PaperIcon } from '@blocksuite/icons'; import { Workspace } from '@blocksuite/store'; import { Command } from 'cmdk'; @@ -7,7 +7,6 @@ import { useRouter } from 'next/router'; import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import usePageHelper from '@/hooks/use-page-helper'; -import { useGlobalState } from '@/store/app'; import { NoResultSVG } from './NoResultSVG'; import { StyledListItem, StyledNotFound } from './style'; @@ -24,7 +23,7 @@ export const PublishedResults = (props: { props; const { search } = usePageHelper(); const [results, setResults] = useState(new Map()); - const dataCenter = useGlobalState(store => store.dataCenter); + const dataCenter = useDataCenter(); const router = useRouter(); const [pageList, setPageList] = useState([]); useEffect(() => { diff --git a/apps/web/src/components/workspace-modal/index.tsx b/apps/web/src/components/workspace-modal/index.tsx index d857810ab9..7ee3b4cd0a 100644 --- a/apps/web/src/components/workspace-modal/index.tsx +++ b/apps/web/src/components/workspace-modal/index.tsx @@ -5,7 +5,7 @@ import { HelpIcon, PlusIcon } from '@blocksuite/icons'; import { useRouter } from 'next/router'; import { useState } from 'react'; -import { useGlobalState } from '@/store/app'; +import { useDataCenter, useGlobalState } from '@/store/app'; import { CreateWorkspaceModal } from '../create-workspace'; import { LoginModal } from '../login-modal'; @@ -34,7 +34,7 @@ interface WorkspaceModalProps { export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => { const [createWorkspaceOpen, setCreateWorkspaceOpen] = useState(false); const logout = useGlobalState(store => store.logout); - const dataCenter = useGlobalState(store => store.dataCenter); + const dataCenter = useDataCenter(); const router = useRouter(); const { t } = useTranslation(); const [loginOpen, setLoginOpen] = useState(false); diff --git a/apps/web/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx b/apps/web/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx index adf69ea871..3e41e083ee 100644 --- a/apps/web/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx +++ b/apps/web/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx @@ -2,7 +2,7 @@ import { useCallback, useState } from 'react'; import { WorkspaceUnitAvatar } from '@/components/workspace-avatar'; import { WorkspaceModal } from '@/components/workspace-modal'; -import { useGlobalState } from '@/store/app'; +import { useDataCenter, useGlobalState } from '@/store/app'; import { SelectorWrapper, WorkspaceName } from './styles'; @@ -11,7 +11,7 @@ export const WorkspaceSelector = () => { const currentWorkspace = useGlobalState( useCallback(store => store.currentDataCenterWorkspace, []) ); - const dataCenter = useGlobalState(useCallback(store => store.dataCenter, [])); + const dataCenter = useDataCenter(); if (dataCenter.workspaces.length === 0) { setWorkspaceListShow(true); diff --git a/apps/web/src/hooks/use-ensure-workspace.ts b/apps/web/src/hooks/use-ensure-workspace.ts index ab31a7dab9..50f90c569a 100644 --- a/apps/web/src/hooks/use-ensure-workspace.ts +++ b/apps/web/src/hooks/use-ensure-workspace.ts @@ -2,13 +2,13 @@ import { assertEquals } from '@blocksuite/global/utils'; import { useRouter } from 'next/router'; import { useCallback, useEffect, useState } from 'react'; -import { useGlobalState } from '@/store/app'; +import { useDataCenter, useGlobalState } from '@/store/app'; // todo: refactor with suspense mode // It is a fully effective hook // Cause it not just ensure workspace loaded, but also have router change. export const useEnsureWorkspace = () => { - const dataCenter = useGlobalState(useCallback(store => store.dataCenter, [])); + const dataCenter = useDataCenter(); const currentWorkspace = useGlobalState( useCallback(store => store.currentDataCenterWorkspace, []) ); diff --git a/apps/web/src/hooks/use-load-public-workspace.ts b/apps/web/src/hooks/use-load-public-workspace.ts index 2f5cf35fc8..aa39afb0b4 100644 --- a/apps/web/src/hooks/use-load-public-workspace.ts +++ b/apps/web/src/hooks/use-load-public-workspace.ts @@ -1,4 +1,5 @@ -import { getDataCenter, WorkspaceUnit } from '@affine/datacenter'; +import { WorkspaceUnit } from '@affine/datacenter'; +import { dataCenterPromise } from '@affine/store'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; @@ -13,7 +14,7 @@ export function useLoadPublicWorkspace(workspaceId: string) { setStatus('loading'); const init = async () => { - const dataCenter = await getDataCenter(); + const dataCenter = await dataCenterPromise; dataCenter .loadPublicWorkspace(workspaceId) diff --git a/apps/web/src/hooks/use-members.ts b/apps/web/src/hooks/use-members.ts index 7672865d0a..92a5d86534 100644 --- a/apps/web/src/hooks/use-members.ts +++ b/apps/web/src/hooks/use-members.ts @@ -1,9 +1,9 @@ import { Member } from '@affine/datacenter'; import { useCallback, useEffect, useState } from 'react'; -import { useGlobalState } from '@/store/app'; +import { useDataCenter, useGlobalState } from '@/store/app'; export const useMembers = () => { - const dataCenter = useGlobalState(store => store.dataCenter); + const dataCenter = useDataCenter(); const currentWorkspace = useGlobalState( useCallback(store => store.currentDataCenterWorkspace, []) ); diff --git a/apps/web/src/hooks/use-workspace-helper.ts b/apps/web/src/hooks/use-workspace-helper.ts index 360ba06dcd..3914938f5c 100644 --- a/apps/web/src/hooks/use-workspace-helper.ts +++ b/apps/web/src/hooks/use-workspace-helper.ts @@ -1,10 +1,10 @@ import { WorkspaceUnit } from '@affine/datacenter'; import { useCallback } from 'react'; -import { useGlobalState } from '@/store/app'; +import { useDataCenter, useGlobalState } from '@/store/app'; export const useWorkspaceHelper = () => { - const dataCenter = useGlobalState(store => store.dataCenter); + const dataCenter = useDataCenter(); const currentWorkspace = useGlobalState( useCallback(store => store.currentDataCenterWorkspace, []) ); diff --git a/apps/web/src/pages/invite/[invite_code].tsx b/apps/web/src/pages/invite/[invite_code].tsx index 9812f1e411..3828d00cdb 100644 --- a/apps/web/src/pages/invite/[invite_code].tsx +++ b/apps/web/src/pages/invite/[invite_code].tsx @@ -11,7 +11,7 @@ import { useEffect, useState } from 'react'; import { PageLoading } from '@/components/loading'; import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; -import { useGlobalState } from '@/store/app'; +import { useDataCenter } from '@/store/app'; import inviteError from '../../../public/imgs/invite-error.svg'; import inviteSuccess from '../../../public/imgs/invite-success.svg'; @@ -21,7 +21,7 @@ export default function DevPage() { const router = useRouter(); const [inviteData, setInviteData] = useState(null); const { acceptInvite } = useWorkspaceHelper(); - const dataCenter = useGlobalState(store => store.dataCenter); + const dataCenter = useDataCenter(); useEffect(() => { const init = async () => { diff --git a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx index ad6a480d63..b3bd7bbc20 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -15,7 +15,7 @@ import { EditorHeader } from '@/components/header'; import MobileModal from '@/components/mobile-modal'; import WorkspaceLayout from '@/components/workspace-layout'; import { usePageHelper } from '@/hooks/use-page-helper'; -import { useGlobalState, useGlobalStateApi } from '@/store/app'; +import { useDataCenter, useGlobalState, useGlobalStateApi } from '@/store/app'; import exampleMarkdown from '@/templates/Welcome-to-AFFiNE-Alpha-Downhills.md'; import type { NextPageWithLayout } from '../..//_app'; @@ -109,7 +109,7 @@ const PageDefender = ({ children }: PropsWithChildren) => { const currentWorkspace = useGlobalState( useCallback(store => store.currentDataCenterWorkspace, []) ); - const dataCenter = useGlobalState(store => store.dataCenter); + const dataCenter = useDataCenter(); const { createPage } = usePageHelper(); useEffect(() => { diff --git a/packages/data-center/src/datacenter.ts b/packages/data-center/src/datacenter.ts index 7d2d3b7043..47e8a1c751 100644 --- a/packages/data-center/src/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -15,6 +15,7 @@ import { createBlocksuiteWorkspace } from './utils'; import { WorkspaceUnit } from './workspace-unit'; import type { WorkspaceUnitCollectionChangeEvent } from './workspace-unit-collection'; import { WorkspaceUnitCollection } from './workspace-unit-collection'; + /** * @class DataCenter * @classdesc Data center is made for managing different providers for business @@ -36,6 +37,10 @@ export class DataCenter { this._logger.enabled = debug; } + static initEmpty() { + return new DataCenter(false); + } + static async init( debug: boolean, exclude: 'affine'[] = [] diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index f76bebce53..d4ea1a0ae4 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -6,17 +6,6 @@ const _initializeDataCenter = () => { return (debug = true) => { if (!_dataCenterInstance) { _dataCenterInstance = DataCenter.init(debug); - _dataCenterInstance.then(dc => { - try { - if (window) { - (window as any).dc = dc; - } - } catch (_) { - // ignore - } - - return dc; - }); } return _dataCenterInstance; diff --git a/packages/store/package.json b/packages/store/package.json index f6babd7dc3..8ccf3e7efc 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -10,6 +10,7 @@ "@blocksuite/react": "0.4.1", "@blocksuite/store": "0.4.1", "react": "^18.2.0", + "swr": "^2.0.3", "zustand": "^4.3.3" }, "devDependencies": { diff --git a/packages/store/src/app/datacenter/index.tsx b/packages/store/src/app/datacenter/index.tsx index a3f7de91ff..f53dc12eb2 100644 --- a/packages/store/src/app/datacenter/index.tsx +++ b/packages/store/src/app/datacenter/index.tsx @@ -2,7 +2,9 @@ import { getDataCenter, WorkspaceUnit } from '@affine/datacenter'; import { DataCenter } from '@affine/datacenter'; import { Disposable, DisposableGroup } from '@blocksuite/global/utils'; import type { PageMeta as StorePageMeta } from '@blocksuite/store'; -import React, { useCallback, useEffect } from 'react'; +import React, { useEffect } from 'react'; +import useSWR from 'swr'; + const DEFAULT_WORKSPACE_NAME = 'Demo Workspace'; export const createDefaultWorkspace = async (dataCenter: DataCenter) => { @@ -11,6 +13,27 @@ export const createDefaultWorkspace = async (dataCenter: DataCenter) => { }); }; +declare global { + // eslint-disable-next-line no-var + var dataCenterPromise: Promise; + // eslint-disable-next-line no-var + var dc: DataCenter; +} + +// eslint-disable-next-line @typescript-eslint/no-non-null-assertion +let dataCenterPromise: Promise = null!; +if (!globalThis.dataCenterPromise) { + dataCenterPromise = getDataCenter(); + dataCenterPromise.then(dataCenter => { + globalThis.dc = dataCenter; + return dataCenter; + }); +} else { + dataCenterPromise = globalThis.dataCenterPromise; +} + +export { dataCenterPromise }; + export interface PageMeta extends StorePageMeta { favorite: boolean; trash: boolean; @@ -19,11 +42,9 @@ export interface PageMeta extends StorePageMeta { mode: 'edgeless' | 'page'; } -import { GlobalActionsCreator, useGlobalState, useGlobalStateApi } from '..'; +import { GlobalActionsCreator, useGlobalStateApi } from '..'; export type DataCenterState = { - readonly dataCenter: DataCenter; - readonly dataCenterPromise: Promise; currentDataCenterWorkspace: WorkspaceUnit | null; dataCenterPageList: PageMeta[]; blobDataSynced: boolean; @@ -37,10 +58,6 @@ export type DataCenterActions = { }; export const createDataCenterState = (): DataCenterState => ({ - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - dataCenter: null!, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - dataCenterPromise: null!, currentDataCenterWorkspace: null, dataCenterPageList: [], blobDataSynced: false, @@ -50,7 +67,8 @@ export const createDataCenterActions: GlobalActionsCreator< DataCenterActions > = (set, get) => ({ loadWorkspace: async (workspaceId, signal) => { - const { dataCenter, currentDataCenterWorkspace } = get(); + const dataCenter = await dataCenterPromise; + const { currentDataCenterWorkspace } = get(); if (!dataCenter.workspaces.find(v => v.id.toString() === workspaceId)) { return null; } @@ -91,11 +109,14 @@ export const createDataCenterActions: GlobalActionsCreator< }, }); +export function useDataCenter() { + const { data } = useSWR(['datacenter'], { + fallbackData: DataCenter.initEmpty(), + }); + return data as DataCenter; +} + export function DataCenterPreloader({ children }: React.PropsWithChildren) { - const dataCenter = useGlobalState(useCallback(store => store.dataCenter, [])); - const dataCenterPromise = useGlobalState( - useCallback(store => store.dataCenterPromise, []) - ); const api = useGlobalStateApi(); //# region effect for updating workspace page list useEffect(() => { @@ -163,31 +184,5 @@ export function DataCenterPreloader({ children }: React.PropsWithChildren) { [api] ); //# endregion - - if (!dataCenter && !dataCenterPromise) { - const promise = getDataCenter(); - api.setState({ dataCenterPromise: promise }); - promise.then(async dataCenter => { - // Ensure datacenter has at least one workspace - if (dataCenter.workspaces.length === 0) { - await createDefaultWorkspace(dataCenter); - } - // set initial state - api.setState({ - dataCenter, - currentWorkspace: null, - currentDataCenterWorkspace: null, - dataCenterPageList: [], - user: - (await dataCenter.getUserInfo( - dataCenter.providers.filter(p => p.id !== 'local')[0]?.id - )) || null, - }); - }); - throw promise; - } - if (!dataCenter) { - throw dataCenterPromise; - } return <>{children}; } diff --git a/packages/store/src/app/index.tsx b/packages/store/src/app/index.tsx index 3564b4454e..4c3fa4e27a 100644 --- a/packages/store/src/app/index.tsx +++ b/packages/store/src/app/index.tsx @@ -1,5 +1,7 @@ +import { assertEquals } from '@blocksuite/global/utils'; import type React from 'react'; import { createContext, useContext, useMemo } from 'react'; +import { preload, SWRConfig, SWRConfiguration } from 'swr'; import { createStore, StateCreator, useStore } from 'zustand'; import { combine, subscribeWithSelector } from 'zustand/middleware'; import type { UseBoundStore } from 'zustand/react'; @@ -13,7 +15,9 @@ import { import { createDataCenterActions, createDataCenterState, + createDefaultWorkspace, DataCenterActions, + dataCenterPromise, DataCenterState, } from './datacenter'; import { @@ -80,11 +84,37 @@ export const useGlobalState: UseBoundStore = (( // eslint-disable-next-line @typescript-eslint/no-explicit-any }) as any; +export type DataKey = ['datacenter', string] | ['datacenter']; + +const swrFetcher = async (keys: DataKey) => { + assertEquals(keys[0], 'datacenter'); + if (keys.length === 1) { + return await dataCenterPromise.then(async dataCenter => { + if (dataCenter.workspaces.length === 0) { + await createDefaultWorkspace(dataCenter); + } + return dataCenter; + }); + } else { + const dataCenter = await dataCenterPromise; + return dataCenter.loadWorkspace(keys[1]); + } +}; + +preload(['datacenter'], swrFetcher); + +const swrConfig: SWRConfiguration = { + fetcher: swrFetcher, + suspense: true, +}; + export const GlobalAppProvider: React.FC = function ModelProvider({ children }) { return ( - create(), [])}> - {children} - + + create(), [])}> + {children} + + ); }; diff --git a/packages/store/src/app/user/index.ts b/packages/store/src/app/user/index.ts index 6a76f0bc2e..cf67e77b69 100644 --- a/packages/store/src/app/user/index.ts +++ b/packages/store/src/app/user/index.ts @@ -1,6 +1,7 @@ import { User } from '@affine/datacenter'; import { GlobalActionsCreator } from '..'; +import { dataCenterPromise } from '../datacenter'; export interface UserState { user: User | null; @@ -24,7 +25,8 @@ export const createUserActions: GlobalActionsCreator = ( ) => { return { login: async () => { - const { dataCenter, currentDataCenterWorkspace: workspace } = get(); + const { currentDataCenterWorkspace: workspace } = get(); + const dataCenter = await dataCenterPromise; try { await dataCenter.login(); const user = (await dataCenter.getUserInfo()) as User; @@ -49,7 +51,7 @@ export const createUserActions: GlobalActionsCreator = ( } }, logout: async () => { - const { dataCenter } = get(); + const dataCenter = await dataCenterPromise; await dataCenter.logout(); set({ user: null }); }, diff --git a/packages/store/src/index.ts b/packages/store/src/index.ts index 066cecc163..e9715f46d0 100644 --- a/packages/store/src/index.ts +++ b/packages/store/src/index.ts @@ -1,3 +1,4 @@ export * from './app'; export type { PageMeta } from './app/datacenter'; export { createDefaultWorkspace, DataCenterPreloader } from './app/datacenter'; +export { dataCenterPromise, useDataCenter } from './app/datacenter'; diff --git a/packages/store/tests/app.spec.tsx b/packages/store/tests/app.spec.tsx index c85f920903..b61a08ebf2 100644 --- a/packages/store/tests/app.spec.tsx +++ b/packages/store/tests/app.spec.tsx @@ -7,11 +7,10 @@ import { DataCenter, getDataCenter } from '@affine/datacenter'; import { createDefaultWorkspace, GlobalAppProvider, + useDataCenter, useGlobalState, - useGlobalStateApi, } from '@affine/store'; import { render } from '@testing-library/react'; -import React from 'react'; import { describe, expect, test } from 'vitest'; describe('App Store', () => { @@ -21,29 +20,16 @@ describe('App Store', () => { await createDefaultWorkspace(dataCenter); const Inner = () => { const state = useGlobalState(); + const dataCenter = useDataCenter(); expect(state).toBeTypeOf('object'); - expect(state.dataCenter).toBeInstanceOf(DataCenter); - expect(state.dataCenterPromise).toBeInstanceOf(Promise); - state.dataCenterPromise.then(dc => expect(dc).toBe(state.dataCenter)); + expect(dataCenter).toBeInstanceOf(DataCenter); return
Test2
; }; - const Loader = ({ children }: React.PropsWithChildren) => { - const api = useGlobalStateApi(); - if (!api.getState().dataCenter) { - api.setState({ - dataCenter, - dataCenterPromise, - }); - } - return <>{children}; - }; const App = () => (
Test1
- - - +
); const app = render(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac67fd04f6..6fcc62fba3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -368,6 +368,7 @@ importers: '@blocksuite/store': 0.4.1 '@types/react': ^18.0.28 react: ^18.2.0 + swr: ^2.0.3 zustand: ^4.3.3 dependencies: '@affine/datacenter': link:../data-center @@ -377,6 +378,7 @@ importers: '@blocksuite/react': 0.4.1_6imdqfxdvhtp63fiogxmlqrieq '@blocksuite/store': 0.4.1 react: 18.2.0 + swr: 2.0.3_react@18.2.0 zustand: 4.3.3_react@18.2.0 devDependencies: '@types/react': 18.0.28 @@ -13950,6 +13952,16 @@ packages: use-sync-external-store: 1.2.0 dev: false + /swr/2.0.3_react@18.2.0: + resolution: {integrity: sha512-sGvQDok/AHEWTPfhUWXEHBVEXmgGnuahyhmRQbjl9XBYxT/MSlAzvXEKQpyM++bMPaI52vcWS2HiKNaW7+9OFw==} + engines: {pnpm: '7'} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + use-sync-external-store: 1.2.0_react@18.2.0 + dev: false + /synchronous-promise/2.0.17: resolution: {integrity: sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==} dev: true