import type { EditorContainer } from '@blocksuite/editor'; import type { Page } from '@blocksuite/store'; import type { ActiveDocProvider, PassiveDocProvider, Workspace as BlockSuiteWorkspace, } from '@blocksuite/store'; import type { FC, PropsWithChildren } from 'react'; import type { Collection } from './filter'; export enum WorkspaceVersion { SubDoc = 2, } export enum WorkspaceSubPath { ALL = 'all', 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 PassiveDocProvider { flavour: 'local-indexeddb-background'; } export interface LocalIndexedDBDownloadProvider extends ActiveDocProvider { flavour: 'local-indexeddb'; } export interface SQLiteProvider extends PassiveDocProvider { flavour: 'sqlite'; } export interface SQLiteDBDownloadProvider extends ActiveDocProvider { flavour: 'sqlite-download'; } // todo: update type with nest.js export type AffineCloudWorkspace = Omit & { flavour: WorkspaceFlavour.AFFINE_CLOUD; }; export interface LocalWorkspace { flavour: WorkspaceFlavour.LOCAL; id: string; blockSuiteWorkspace: BlockSuiteWorkspace; } export interface AffinePublicWorkspace { flavour: WorkspaceFlavour.PUBLIC; id: string; blockSuiteWorkspace: BlockSuiteWorkspace; } 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', 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.PUBLIC]: AffinePublicWorkspace; [WorkspaceFlavour.AFFINE_CLOUD]: AffineCloudWorkspace; } export interface WorkspaceCRUD { create: (blockSuiteWorkspace: BlockSuiteWorkspace) => Promise; delete: (workspace: WorkspaceRegistry[Flavour]) => Promise; get: (workspaceId: string) => Promise; // not supported yet // update: (workspace: FlavourToWorkspace[Flavour]) => Promise; list: () => Promise; } type UIBaseProps = { currentWorkspace: WorkspaceRegistry[Flavour]; }; export type WorkspaceHeaderProps = UIBaseProps & { currentEntry: | { subPath: WorkspaceSubPath; } | { pageId: string; }; }; type NewSettingProps = UIBaseProps & { onDeleteWorkspace: () => Promise; 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; }; type PageListProps<_Flavour extends keyof WorkspaceRegistry> = { blockSuiteWorkspace: BlockSuiteWorkspace; onOpenPage: (pageId: string, newTab?: boolean) => void; collection: Collection; }; export interface WorkspaceUISchema { Header: FC>; PageDetail: FC>; PageList: FC>; NewSettingsDetail: FC>; Provider: FC; } export interface AppEvents { // event there is no workspace // usually used to initialize workspace plugin 'app:init': () => string[]; // request to gain access to workspace plugin 'workspace:access': () => Promise; // request to revoke access to workspace plugin 'workspace:revoke': () => Promise; } 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; }