import type { EditorContainer } from '@blocksuite/editor'; import type { Page } from '@blocksuite/store'; import type { ActiveDocProvider, PassiveDocProvider, Workspace as BlockSuiteWorkspace, } from '@blocksuite/store'; import type { PropsWithChildren, ReactNode } from 'react'; import type { DataSourceAdapter } from 'y-provider'; export enum WorkspaceSubPath { ALL = 'all', Collection = 'collection', SETTING = 'setting', TRASH = 'trash', SHARED = 'shared', } export interface AffineDownloadProvider extends PassiveDocProvider { flavour: 'affine-download'; } /** * Download the first binary from local IndexedDB */ export interface BroadCastChannelProvider extends PassiveDocProvider { flavour: 'broadcast-channel'; } /** * Long polling provider with local IndexedDB */ export interface LocalIndexedDBBackgroundProvider extends DataSourceAdapter, PassiveDocProvider { flavour: 'local-indexeddb-background'; } export interface LocalIndexedDBDownloadProvider extends ActiveDocProvider { flavour: 'local-indexeddb'; } export interface SQLiteProvider extends PassiveDocProvider, DataSourceAdapter { flavour: 'sqlite'; } export interface SQLiteDBDownloadProvider extends ActiveDocProvider { flavour: 'sqlite-download'; } export interface AffineSocketIOProvider extends PassiveDocProvider, DataSourceAdapter { flavour: 'affine-socket-io'; } type BaseWorkspace = { flavour: string; id: string; blockSuiteWorkspace: BlockSuiteWorkspace; }; export interface AffineCloudWorkspace extends BaseWorkspace { flavour: WorkspaceFlavour.AFFINE_CLOUD; id: string; blockSuiteWorkspace: BlockSuiteWorkspace; } export interface LocalWorkspace extends BaseWorkspace { flavour: WorkspaceFlavour.LOCAL; id: string; blockSuiteWorkspace: BlockSuiteWorkspace; } export interface AffinePublicWorkspace extends BaseWorkspace { flavour: WorkspaceFlavour.AFFINE_PUBLIC; id: string; blockSuiteWorkspace: BlockSuiteWorkspace; } export type AffineOfficialWorkspace = | AffineCloudWorkspace | LocalWorkspace | AffinePublicWorkspace; export enum ReleaseType { // if workspace is not released yet, we will not show it in the workspace list UNRELEASED = 'unreleased', STABLE = 'stable', } export enum LoadPriority { HIGH = 1, MEDIUM = 2, LOW = 3, } export enum WorkspaceFlavour { /** * New AFFiNE Cloud Workspace using Nest.js Server. */ AFFINE_CLOUD = 'affine-cloud', LOCAL = 'local', AFFINE_PUBLIC = 'affine-public', } export const settingPanel = { General: 'general', Collaboration: 'collaboration', Publish: 'publish', Export: 'export', Sync: 'sync', } as const; export const settingPanelValues = [...Object.values(settingPanel)] as const; export type SettingPanel = (typeof settingPanel)[keyof typeof settingPanel]; // built-in workspaces export interface WorkspaceRegistry { [WorkspaceFlavour.LOCAL]: LocalWorkspace; [WorkspaceFlavour.AFFINE_PUBLIC]: AffinePublicWorkspace; [WorkspaceFlavour.AFFINE_CLOUD]: AffineCloudWorkspace; } export interface WorkspaceCRUD { create: (blockSuiteWorkspace: BlockSuiteWorkspace) => Promise; delete: (blockSuiteWorkspace: BlockSuiteWorkspace) => Promise; get: (workspaceId: string) => Promise; // not supported yet // update: (workspace: FlavourToWorkspace[Flavour]) => Promise; list: () => Promise; } type UIBaseProps<_Flavour extends keyof WorkspaceRegistry> = { currentWorkspaceId: string; }; export type WorkspaceHeaderProps = UIBaseProps & { rightSlot?: ReactNode; currentEntry: | { subPath: WorkspaceSubPath; } | { pageId: string; }; }; type NewSettingProps = UIBaseProps & { onDeleteLocalWorkspace: () => void; onDeleteCloudWorkspace: () => void; onLeaveWorkspace: () => void; onTransformWorkspace: < From extends keyof WorkspaceRegistry, To extends keyof WorkspaceRegistry, >( from: From, to: To, workspace: WorkspaceRegistry[From] ) => void; }; type PageDetailProps = UIBaseProps & { currentPageId: string; onLoadEditor: (page: Page, editor: EditorContainer) => () => void; }; interface FC

{ (props: P): ReactNode; } export interface WorkspaceUISchema { PageDetail: FC>; NewSettingsDetail: FC>; Provider: FC; LoginCard?: FC; } export interface AppEvents { // event there is no workspace // usually used to initialize workspace adapter 'app:init': () => string[]; // event if you have access to workspace adapter 'app:access': () => Promise; 'service:start': () => void; 'service:stop': () => void; } export interface WorkspaceAdapter { releaseType: ReleaseType; flavour: Flavour; // The Adapter will be loaded according to the priority loadPriority: LoadPriority; Events: Partial; // Fetch necessary data for the first render CRUD: WorkspaceCRUD; UI: WorkspaceUISchema; }