mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-24 21:43:40 +03:00
refactor(plugin-infra): workspace loading (#3222)
This commit is contained in:
parent
23ac82f845
commit
1f5995ffc7
@ -22,7 +22,9 @@
|
|||||||
"templates",
|
"templates",
|
||||||
"y-indexeddb",
|
"y-indexeddb",
|
||||||
"debug",
|
"debug",
|
||||||
"storage"
|
"storage",
|
||||||
|
"infra",
|
||||||
|
"plugin-infra"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import {
|
|||||||
import { createIndexedDBDownloadProvider } from '@affine/workspace/providers';
|
import { createIndexedDBDownloadProvider } from '@affine/workspace/providers';
|
||||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { nanoid } from '@blocksuite/store';
|
import { nanoid } from '@blocksuite/store';
|
||||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
import { useStaticBlockSuiteWorkspace } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BlockSuitePageList,
|
BlockSuitePageList,
|
||||||
|
@ -6,8 +6,8 @@ import { WorkspaceAvatar } from '@affine/component/workspace-avatar';
|
|||||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||||
import type { RootWorkspaceMetadata } from '@affine/workspace/atom';
|
import type { RootWorkspaceMetadata } from '@affine/workspace/atom';
|
||||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
|
||||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||||
|
import { useStaticBlockSuiteWorkspace } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { WorkspaceDetailSkeleton } from '@affine/component/setting-components';
|
import { WorkspaceDetailSkeleton } from '@affine/component/setting-components';
|
||||||
import { usePassiveWorkspaceEffect } from '@toeverything/hooks/use-block-suite-workspace';
|
import { usePassiveWorkspaceEffect } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||||
import { useSetAtom } from 'jotai';
|
import { useSetAtom } from 'jotai';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { Suspense, useCallback } from 'react';
|
import { Suspense, useCallback } from 'react';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
import type { Workspace } from '@blocksuite/store';
|
import type { Workspace } from '@blocksuite/store';
|
||||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
import { useStaticBlockSuiteWorkspace } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||||
import type { Atom } from 'jotai';
|
import type { Atom } from 'jotai';
|
||||||
import { atom, useAtomValue } from 'jotai';
|
import { atom, useAtomValue } from 'jotai';
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
|||||||
import { saveWorkspaceToLocalStorage } from '@affine/workspace/local/crud';
|
import { saveWorkspaceToLocalStorage } from '@affine/workspace/local/crud';
|
||||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { nanoid } from '@blocksuite/store';
|
import { nanoid } from '@blocksuite/store';
|
||||||
import { getWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
import { getWorkspace } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||||
import { useAtomValue, useSetAtom } from 'jotai';
|
import { useAtomValue, useSetAtom } from 'jotai';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@ import {
|
|||||||
useSensor,
|
useSensor,
|
||||||
useSensors,
|
useSensors,
|
||||||
} from '@dnd-kit/core';
|
} from '@dnd-kit/core';
|
||||||
import { usePassiveWorkspaceEffect } from '@toeverything/hooks/use-block-suite-workspace';
|
|
||||||
import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper';
|
import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper';
|
||||||
|
import { usePassiveWorkspaceEffect } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||||
import {
|
import {
|
||||||
currentPageIdAtom,
|
currentPageIdAtom,
|
||||||
currentWorkspaceIdAtom,
|
currentWorkspaceIdAtom,
|
||||||
|
@ -2,7 +2,7 @@ import { WorkspaceFallback } from '@affine/component/workspace';
|
|||||||
import { DebugLogger } from '@affine/debug';
|
import { DebugLogger } from '@affine/debug';
|
||||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||||
import { getWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
import { getWorkspace } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
import type { NextPage } from 'next';
|
import type { NextPage } from 'next';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
@ -12,7 +12,6 @@ export const BlockHubWrapper = (props: BlockHubProps): ReactElement => {
|
|||||||
const blockHub = useAtomValue(props.blockHubAtom);
|
const blockHub = useAtomValue(props.blockHubAtom);
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('ref.current', blockHub, ref);
|
|
||||||
if (ref.current) {
|
if (ref.current) {
|
||||||
const div = ref.current;
|
const div = ref.current;
|
||||||
if (blockHub) {
|
if (blockHub) {
|
||||||
|
@ -8,8 +8,8 @@ import {
|
|||||||
LocalDataIcon as DefaultLocalDataIcon,
|
LocalDataIcon as DefaultLocalDataIcon,
|
||||||
LocalWorkspaceIcon as DefaultLocalWorkspaceIcon,
|
LocalWorkspaceIcon as DefaultLocalWorkspaceIcon,
|
||||||
} from '@blocksuite/icons';
|
} from '@blocksuite/icons';
|
||||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/hooks/use-block-suite-workspace';
|
|
||||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||||
|
import { useStaticBlockSuiteWorkspace } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
@ -18,17 +18,19 @@
|
|||||||
"type": "./dist/type.d.ts",
|
"type": "./dist/type.d.ts",
|
||||||
"import": "./dist/type.js",
|
"import": "./dist/type.js",
|
||||||
"require": "./dist/type.cjs"
|
"require": "./dist/type.cjs"
|
||||||
|
},
|
||||||
|
"./__internal__/workspace": {
|
||||||
|
"type": "./dist/__internal__/workspace.d.ts",
|
||||||
|
"import": "./dist/__internal__/workspace.js",
|
||||||
|
"require": "./dist/__internal__/workspace.cjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"devDependencies": {
|
||||||
"@blocksuite/blocks": "0.0.0-20230713062147-9eb7708c-nightly",
|
"@blocksuite/blocks": "0.0.0-20230713062147-9eb7708c-nightly",
|
||||||
"@blocksuite/editor": "0.0.0-20230713062147-9eb7708c-nightly",
|
"@blocksuite/editor": "0.0.0-20230713062147-9eb7708c-nightly",
|
||||||
"@blocksuite/global": "0.0.0-20230713062147-9eb7708c-nightly",
|
"@blocksuite/global": "0.0.0-20230713062147-9eb7708c-nightly",
|
||||||
"@blocksuite/lit": "0.0.0-20230713062147-9eb7708c-nightly",
|
"@blocksuite/lit": "0.0.0-20230713062147-9eb7708c-nightly",
|
||||||
"@blocksuite/store": "0.0.0-20230713062147-9eb7708c-nightly",
|
"@blocksuite/store": "0.0.0-20230713062147-9eb7708c-nightly",
|
||||||
"jotai": "^2.2.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"jotai": "^2.2.2",
|
"jotai": "^2.2.2",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"vite-plugin-dts": "3.0.2"
|
"vite-plugin-dts": "3.0.2"
|
||||||
|
@ -17,10 +17,25 @@ const workspacePassiveAtomWeakMap = new WeakMap<
|
|||||||
>();
|
>();
|
||||||
|
|
||||||
// Whether the workspace is active to use
|
// Whether the workspace is active to use
|
||||||
const workspaceActiveWeakMap = new WeakMap<Workspace, boolean>();
|
export const workspaceActiveWeakMap = new WeakMap<Workspace, boolean>();
|
||||||
|
|
||||||
// Whether the workspace has been enabled the passive effect (background)
|
// Whether the workspace has been enabled the passive effect (background)
|
||||||
const workspacePassiveEffectWeakMap = new WeakMap<Workspace, boolean>();
|
export const workspacePassiveEffectWeakMap = new WeakMap<Workspace, boolean>();
|
||||||
|
|
||||||
|
export async function waitForWorkspace(workspace: Workspace) {
|
||||||
|
if (workspaceActiveWeakMap.get(workspace) !== true) {
|
||||||
|
const providers = workspace.providers.filter(
|
||||||
|
(provider): provider is ActiveDocProvider =>
|
||||||
|
'active' in provider && provider.active === true
|
||||||
|
);
|
||||||
|
for (const provider of providers) {
|
||||||
|
provider.sync();
|
||||||
|
// we will wait for the necessary providers to be ready
|
||||||
|
await provider.whenReady;
|
||||||
|
}
|
||||||
|
workspaceActiveWeakMap.set(workspace, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getWorkspace(id: string) {
|
export function getWorkspace(id: string) {
|
||||||
if (!INTERNAL_BLOCKSUITE_HASH_MAP.has(id)) {
|
if (!INTERNAL_BLOCKSUITE_HASH_MAP.has(id)) {
|
||||||
@ -38,18 +53,7 @@ export function getActiveBlockSuiteWorkspaceAtom(
|
|||||||
const workspace = INTERNAL_BLOCKSUITE_HASH_MAP.get(id) as Workspace;
|
const workspace = INTERNAL_BLOCKSUITE_HASH_MAP.get(id) as Workspace;
|
||||||
if (!workspacePassiveAtomWeakMap.has(workspace)) {
|
if (!workspacePassiveAtomWeakMap.has(workspace)) {
|
||||||
const baseAtom = atom(async () => {
|
const baseAtom = atom(async () => {
|
||||||
if (workspaceActiveWeakMap.get(workspace) !== true) {
|
await waitForWorkspace(workspace);
|
||||||
const providers = workspace.providers.filter(
|
|
||||||
(provider): provider is ActiveDocProvider =>
|
|
||||||
'active' in provider && provider.active === true
|
|
||||||
);
|
|
||||||
for (const provider of providers) {
|
|
||||||
provider.sync();
|
|
||||||
// we will wait for the necessary providers to be ready
|
|
||||||
await provider.whenReady;
|
|
||||||
}
|
|
||||||
workspaceActiveWeakMap.set(workspace, true);
|
|
||||||
}
|
|
||||||
return workspace;
|
return workspace;
|
||||||
});
|
});
|
||||||
workspacePassiveAtomWeakMap.set(workspace, baseAtom);
|
workspacePassiveAtomWeakMap.set(workspace, baseAtom);
|
@ -3,14 +3,15 @@
|
|||||||
*/
|
*/
|
||||||
import { Workspace } from '@blocksuite/store';
|
import { Workspace } from '@blocksuite/store';
|
||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
|
import { getDefaultStore } from 'jotai/vanilla';
|
||||||
|
import { expect, test, vi } from 'vitest';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getActiveBlockSuiteWorkspaceAtom,
|
getActiveBlockSuiteWorkspaceAtom,
|
||||||
INTERNAL_BLOCKSUITE_HASH_MAP,
|
INTERNAL_BLOCKSUITE_HASH_MAP,
|
||||||
usePassiveWorkspaceEffect,
|
usePassiveWorkspaceEffect,
|
||||||
useStaticBlockSuiteWorkspace,
|
useStaticBlockSuiteWorkspace,
|
||||||
} from '@toeverything/hooks/use-block-suite-workspace';
|
} from '../__internal__/workspace';
|
||||||
import { getDefaultStore } from 'jotai/vanilla';
|
|
||||||
import { expect, test, vi } from 'vitest';
|
|
||||||
|
|
||||||
test('useStaticBlockSuiteWorkspace', async () => {
|
test('useStaticBlockSuiteWorkspace', async () => {
|
||||||
const sync = vi.fn();
|
const sync = vi.fn();
|
@ -1,5 +1,8 @@
|
|||||||
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
|
import type { Page, Workspace } from '@blocksuite/store';
|
||||||
import { atom, createStore } from 'jotai/vanilla';
|
import { atom, createStore } from 'jotai/vanilla';
|
||||||
|
|
||||||
|
import { getWorkspace, waitForWorkspace } from './__internal__/workspace';
|
||||||
import type { AffinePlugin, Definition, ServerAdapter } from './type';
|
import type { AffinePlugin, Definition, ServerAdapter } from './type';
|
||||||
import type { Loader, PluginUIAdapter } from './type';
|
import type { Loader, PluginUIAdapter } from './type';
|
||||||
import type { PluginBlockSuiteAdapter } from './type';
|
import type { PluginBlockSuiteAdapter } from './type';
|
||||||
@ -12,8 +15,29 @@ export const rootStore = createStore();
|
|||||||
|
|
||||||
// todo: for now every plugin is enabled by default
|
// todo: for now every plugin is enabled by default
|
||||||
export const affinePluginsAtom = atom<Record<string, AffinePlugin<string>>>({});
|
export const affinePluginsAtom = atom<Record<string, AffinePlugin<string>>>({});
|
||||||
export const currentPageIdAtom = atom<string | null>(null);
|
|
||||||
export const currentWorkspaceIdAtom = atom<string | null>(null);
|
export const currentWorkspaceIdAtom = atom<string | null>(null);
|
||||||
|
export const currentPageIdAtom = atom<string | null>(null);
|
||||||
|
export const currentWorkspaceAtom = atom<Promise<Workspace>>(async get => {
|
||||||
|
const currentWorkspaceId = get(currentWorkspaceIdAtom);
|
||||||
|
assertExists(currentWorkspaceId, 'current workspace id');
|
||||||
|
const workspace = getWorkspace(currentWorkspaceId);
|
||||||
|
await waitForWorkspace(workspace);
|
||||||
|
return workspace;
|
||||||
|
});
|
||||||
|
export const currentPageAtom = atom<Promise<Page>>(async get => {
|
||||||
|
const currentWorkspaceId = get(currentWorkspaceIdAtom);
|
||||||
|
assertExists(currentWorkspaceId, 'current workspace id');
|
||||||
|
const currentPageId = get(currentPageIdAtom);
|
||||||
|
assertExists(currentPageId, 'current page id');
|
||||||
|
const workspace = getWorkspace(currentWorkspaceId);
|
||||||
|
await waitForWorkspace(workspace);
|
||||||
|
const page = workspace.getPage(currentPageId);
|
||||||
|
assertExists(page);
|
||||||
|
if (!page.loaded) {
|
||||||
|
await page.waitForLoaded();
|
||||||
|
}
|
||||||
|
return page;
|
||||||
|
});
|
||||||
|
|
||||||
export function definePlugin<ID extends string>(
|
export function definePlugin<ID extends string>(
|
||||||
definition: Definition<ID>,
|
definition: Definition<ID>,
|
||||||
|
@ -13,18 +13,14 @@ export default defineConfig({
|
|||||||
entry: {
|
entry: {
|
||||||
type: resolve(root, 'src/type.ts'),
|
type: resolve(root, 'src/type.ts'),
|
||||||
manager: resolve(root, 'src/manager.ts'),
|
manager: resolve(root, 'src/manager.ts'),
|
||||||
|
'__internal__/workspace': resolve(
|
||||||
|
root,
|
||||||
|
'src/__internal__/workspace.ts'
|
||||||
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: [
|
external: ['react', /^jotai/, /^@blocksuite/],
|
||||||
'jotai',
|
|
||||||
'jotai/vanilla',
|
|
||||||
'@blocksuite/blocks',
|
|
||||||
'@blocksuite/store',
|
|
||||||
'@blocksuite/global',
|
|
||||||
'@blocksuite/editor',
|
|
||||||
'@blocksuite/lit',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
Generator,
|
Generator,
|
||||||
Workspace,
|
Workspace,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
import { INTERNAL_BLOCKSUITE_HASH_MAP } from '@toeverything/hooks/use-block-suite-workspace';
|
import { INTERNAL_BLOCKSUITE_HASH_MAP } from '@toeverything/plugin-infra/__internal__/workspace';
|
||||||
|
|
||||||
import { createStaticStorage } from './blob/local-static-storage';
|
import { createStaticStorage } from './blob/local-static-storage';
|
||||||
import { createSQLiteStorage } from './blob/sqlite-blob-storage';
|
import { createSQLiteStorage } from './blob/sqlite-blob-storage';
|
||||||
|
Loading…
Reference in New Issue
Block a user