diff --git a/README.md b/README.md index 508441bfe8..b6e318484e 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,6 @@ If you have questions, you are welcome to contact us. One of the best places to | Official Plugin | Description | Status | | ----------------------------------------------------- | ----------------------------------------- | ------ | -| [@affine/bookmark-plugin](plugins/bookmark) | A block for bookmarking a website | ✅ | | [@affine/copilot-plugin](plugins/copilot) | AI Copilot that help you document writing | 🚧 | | [@affine/image-preview-plugin](plugins/image-preview) | Component for previewing an image | ✅ | | [@affine/outline](plugins/outline) | Outline for your document | ✅ | diff --git a/plugins/bookmark/src/app.tsx b/apps/core/src/components/bookmark.tsx similarity index 94% rename from plugins/bookmark/src/app.tsx rename to apps/core/src/components/bookmark.tsx index 7cf6a57c48..6836eecd5c 100644 --- a/plugins/bookmark/src/app.tsx +++ b/apps/core/src/components/bookmark.tsx @@ -4,14 +4,8 @@ import type { SerializedBlock } from '@blocksuite/blocks'; import type { BaseBlockModel } from '@blocksuite/store'; import type { Page } from '@blocksuite/store'; import type { VEditor } from '@blocksuite/virgo'; -import type { ReactElement } from 'react'; -import { StrictMode } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react'; -export type BookMarkProps = { - page: Page; -}; - type ShortcutMap = { [key: string]: (e: KeyboardEvent, page: Page) => void; }; @@ -121,7 +115,11 @@ const shouldShowBookmarkMenu = (pastedBlocks: Record[]) => { return !!firstBlock.text[0].attributes?.link; }; -const BookMarkUI = ({ page }: BookMarkProps) => { +export type BookmarkProps = { + page: Page; +}; + +export const Bookmark = ({ page }: BookmarkProps) => { const [anchor, setAnchor] = useState(null); const [selectedOption, setSelectedOption] = useState( menuOptions[0].id @@ -244,15 +242,3 @@ const BookMarkUI = ({ page }: BookMarkProps) => { ) : null; }; - -type AppProps = { - page: Page; -}; - -export const App = (props: AppProps): ReactElement => { - return ( - - - - ); -}; diff --git a/apps/core/src/components/page-detail-editor.tsx b/apps/core/src/components/page-detail-editor.tsx index 1d30cd7498..43b039f8b5 100644 --- a/apps/core/src/components/page-detail-editor.tsx +++ b/apps/core/src/components/page-detail-editor.tsx @@ -31,6 +31,7 @@ import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels'; import { pageSettingFamily } from '../atoms'; import { fontStyleOptions, useAppSetting } from '../atoms/settings'; import { BlockSuiteEditor as Editor } from './blocksuite/block-suite-editor'; +import { Bookmark } from './bookmark'; import * as styles from './page-detail-editor.css'; import { editorContainer, pluginContainer } from './page-detail-editor.css'; import { TrashButtonGroup } from './pure/trash-button-group'; @@ -139,6 +140,7 @@ const EditorWrapper = memo(function EditorWrapper({ )} /> {meta.trash && } + ); }); diff --git a/apps/electron/package.json b/apps/electron/package.json index 2bbf1abd70..d656402b75 100644 --- a/apps/electron/package.json +++ b/apps/electron/package.json @@ -26,7 +26,6 @@ "main": "./dist/main.js", "devDependencies": { "@affine-test/kit": "workspace:*", - "@affine/bookmark-plugin": "workspace:*", "@affine/copilot-plugin": "workspace:*", "@affine/env": "workspace:*", "@affine/hello-world-plugin": "workspace:*", diff --git a/apps/electron/scripts/common.mjs b/apps/electron/scripts/common.mjs index e9a03d3bb4..660811f7b5 100644 --- a/apps/electron/scripts/common.mjs +++ b/apps/electron/scripts/common.mjs @@ -32,7 +32,6 @@ export const config = () => { resolve(electronDir, './src/main/index.ts'), resolve(electronDir, './src/preload/index.ts'), resolve(electronDir, './src/helper/index.ts'), - resolve(electronDir, './src/worker/plugin.ts'), ], entryNames: '[dir]', outdir: resolve(electronDir, './dist'), diff --git a/apps/electron/src/main/handlers.ts b/apps/electron/src/main/handlers.ts index 0da50044f7..0f3fe497bf 100644 --- a/apps/electron/src/main/handlers.ts +++ b/apps/electron/src/main/handlers.ts @@ -64,7 +64,6 @@ export const registerHandlers = () => { ipcMain.handle(chan, async (e, ...args) => { const start = performance.now(); try { - // @ts-expect-error - TODO: fix this const result = await handler(e, ...args); logger.info( '[ipc-api]', diff --git a/apps/electron/src/main/index.ts b/apps/electron/src/main/index.ts index 7df7f84daa..fb24f7b1e6 100644 --- a/apps/electron/src/main/index.ts +++ b/apps/electron/src/main/index.ts @@ -9,7 +9,6 @@ import { registerHandlers } from './handlers'; import { ensureHelperProcess } from './helper-process'; import { logger } from './logger'; import { restoreOrCreateWindow } from './main-window'; -import { registerPlugin } from './plugin'; import { registerProtocol } from './protocol'; import { registerUpdater } from './updater'; @@ -59,7 +58,6 @@ setupDeepLink(app); app .whenReady() .then(registerProtocol) - .then(registerPlugin) .then(registerHandlers) .then(registerEvents) .then(ensureHelperProcess) diff --git a/apps/electron/src/main/plugin.ts b/apps/electron/src/main/plugin.ts deleted file mode 100644 index 4f12c160b0..0000000000 --- a/apps/electron/src/main/plugin.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { join, resolve } from 'node:path'; -import { Worker } from 'node:worker_threads'; - -import { logger, pluginLogger } from '@affine/electron/main/logger'; -import { AsyncCall } from 'async-call-rpc'; -import { ipcMain } from 'electron'; -import { readFile } from 'fs/promises'; - -import { MessageEventChannel } from '../shared/utils'; - -const builtInPlugins = ['bookmark']; - -declare global { - // fixme(himself65): - // remove this when bookmark block plugin is migrated to plugin-infra - // eslint-disable-next-line no-var - var asyncCall: Record PromiseLike>; -} - -export async function registerPlugin() { - logger.info('import plugin manager'); - const asyncCall = AsyncCall< - Record PromiseLike> - >( - { - log: (...args: any[]) => { - pluginLogger.log(...args); - }, - }, - { - channel: new MessageEventChannel( - new Worker(resolve(__dirname, './worker.js'), {}) - ), - } - ); - globalThis.asyncCall = asyncCall; - await Promise.all( - builtInPlugins.map(async plugin => { - const pluginPackageJsonPath = join( - process.env.PLUGIN_DIR ?? resolve(__dirname, './plugins'), - `./${plugin}/package.json` - ); - logger.info(`${plugin} plugin path:`, pluginPackageJsonPath); - const packageJson = JSON.parse( - await readFile(pluginPackageJsonPath, 'utf-8') - ); - console.log('packageJson', packageJson); - const serverCommand: string[] = packageJson.affinePlugin.serverCommand; - serverCommand.forEach(command => { - ipcMain.handle(command, async (_, ...args) => { - logger.info(`plugin ${plugin} called`); - return asyncCall[command](...args); - }); - }); - }) - ); -} diff --git a/apps/electron/src/main/ui/handlers.ts b/apps/electron/src/main/ui/handlers.ts index 90c5f60619..607ae69b2e 100644 --- a/apps/electron/src/main/ui/handlers.ts +++ b/apps/electron/src/main/ui/handlers.ts @@ -1,4 +1,5 @@ import { app, BrowserWindow, nativeTheme } from 'electron'; +import { getLinkPreview } from 'link-preview-js'; import { isMacOS } from '../../shared/utils'; import type { NamespaceHandlers } from '../type'; @@ -43,12 +44,30 @@ export const uiHandlers = { getGoogleOauthCode: async () => { return getGoogleOauthCode(); }, - /** - * @deprecated Remove this when bookmark block plugin is migrated to plugin-infra - */ getBookmarkDataByLink: async (_, link: string) => { - return globalThis.asyncCall[ - 'com.blocksuite.bookmark-block.get-bookmark-data-by-link' - ](link); + const previewData = (await getLinkPreview(link, { + timeout: 6000, + headers: { + 'user-agent': 'googlebot', + }, + followRedirects: 'follow', + }).catch(() => { + return { + title: '', + siteName: '', + description: '', + images: [], + videos: [], + contentType: `text/html`, + favicons: [], + }; + })) as any; + + return { + title: previewData.title, + description: previewData.description, + icon: previewData.favicons[0], + image: previewData.images[0], + }; }, } satisfies NamespaceHandlers; diff --git a/apps/electron/src/worker/plugin.ts b/apps/electron/src/worker/plugin.ts deleted file mode 100644 index 0126c1125e..0000000000 --- a/apps/electron/src/worker/plugin.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { join, resolve } from 'node:path'; -import { parentPort } from 'node:worker_threads'; - -import type { ServerContext } from '@affine/sdk/server'; -import { AsyncCall } from 'async-call-rpc'; - -import { MessageEventChannel } from '../shared/utils'; - -if (!parentPort) { - throw new Error('parentPort is null'); -} -const commandProxy: Record Promise> = {}; - -parentPort.start(); - -const mainThread = AsyncCall<{ - log: (...args: any[]) => Promise; -}>(commandProxy, { - channel: new MessageEventChannel(parentPort), -}); - -// eslint-disable-next-line @typescript-eslint/no-misused-promises -globalThis.console.log = mainThread.log; -// eslint-disable-next-line @typescript-eslint/no-misused-promises -globalThis.console.error = mainThread.log; -// eslint-disable-next-line @typescript-eslint/no-misused-promises -globalThis.console.info = mainThread.log; -// eslint-disable-next-line @typescript-eslint/no-misused-promises -globalThis.console.debug = mainThread.log; -// eslint-disable-next-line @typescript-eslint/no-misused-promises -globalThis.console.warn = mainThread.log; - -// eslint-disable-next-line @typescript-eslint/no-var-requires -const bookmarkPluginModule = require( - join( - process.env.PLUGIN_DIR ?? resolve(__dirname, './plugins'), - './bookmark/index.cjs' - ) -); - -const serverContext: ServerContext = { - registerCommand: (command, fn) => { - console.log('register command', command); - commandProxy[command] = fn; - }, - unregisterCommand: command => { - console.log('unregister command', command); - delete commandProxy[command]; - }, -}; - -bookmarkPluginModule.entry(serverContext); diff --git a/packages/infra/src/__internal__/plugin.ts b/packages/infra/src/__internal__/plugin.ts index b36476689f..7273fb2486 100644 --- a/packages/infra/src/__internal__/plugin.ts +++ b/packages/infra/src/__internal__/plugin.ts @@ -42,7 +42,6 @@ export const pluginPackageJson = atom< >([]); export const enabledPluginAtom = atomWithStorage('affine-enabled-plugin', [ - '@affine/bookmark-plugin', '@affine/image-preview-plugin', '@affine/outline-plugin', ]); diff --git a/packages/infra/src/type.ts b/packages/infra/src/type.ts index 9631797acd..d370670a3e 100644 --- a/packages/infra/src/type.ts +++ b/packages/infra/src/type.ts @@ -15,9 +15,7 @@ export const packageJsonInputSchema = z.object({ release: z.union([z.boolean(), z.enum(['development'])]), entry: z.object({ core: z.string(), - server: z.string().optional(), }), - serverCommand: z.array(z.string()).optional(), }), }); @@ -31,7 +29,6 @@ export const packageJsonOutputSchema = z.object({ core: z.string(), }), assets: z.array(z.string()), - serverCommand: z.array(z.string()).optional(), }), }); diff --git a/packages/plugin-cli/src/af.ts b/packages/plugin-cli/src/af.ts index 9cf3b7b5dd..c94a6d9cb9 100644 --- a/packages/plugin-cli/src/af.ts +++ b/packages/plugin-cli/src/af.ts @@ -64,9 +64,6 @@ const external = [ // css /^@vanilla-extract/, - - // remove this when bookmark plugin is ready - 'link-preview-js', ]; const allPluginDir = path.resolve(projectRoot, 'plugins'); @@ -103,15 +100,6 @@ const outDir = path.resolve(projectRoot, 'apps', 'core', 'public', 'plugins'); const coreOutDir = path.resolve(outDir, plugin); -const serverOutDir = path.resolve( - projectRoot, - 'apps', - 'electron', - 'dist', - 'plugins', - plugin -); - const coreEntry = path.resolve(pluginDir, json.affinePlugin.entry.core); const generatePackageJson: PluginOption = { @@ -127,7 +115,6 @@ const generatePackageJson: PluginOption = { core: 'index.js', }, assets: [...metadata.assets], - serverCommand: json.affinePlugin.serverCommand, }, } satisfies z.infer; packageJsonOutputSchema.parse(packageJson); @@ -191,25 +178,3 @@ await build({ generatePackageJson, ], }); - -// step 2: generate server bundle -if (json.affinePlugin.entry.server) { - const serverEntry = path.resolve(pluginDir, json.affinePlugin.entry.server); - await build({ - build: { - watch: isWatch ? {} : undefined, - minify: false, - outDir: serverOutDir, - emptyOutDir: true, - lib: { - entry: serverEntry, - fileName: 'index', - formats: ['cjs'], - }, - rollupOptions: { - external, - }, - }, - plugins: [generatePackageJson], - }); -} diff --git a/plugins/bookmark/README.md b/plugins/bookmark/README.md deleted file mode 100644 index 164fb08889..0000000000 --- a/plugins/bookmark/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# AFFiNE Bookmark - -> Bookmark plugin - -![preview](assets/preview.png) diff --git a/plugins/bookmark/assets/preview.png b/plugins/bookmark/assets/preview.png deleted file mode 100644 index d6b3c3ca0c..0000000000 Binary files a/plugins/bookmark/assets/preview.png and /dev/null differ diff --git a/plugins/bookmark/package.json b/plugins/bookmark/package.json deleted file mode 100644 index a66d7eafcf..0000000000 --- a/plugins/bookmark/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "@affine/bookmark-plugin", - "type": "module", - "version": "0.9.0-canary.13", - "description": "Bookmark Plugin", - "affinePlugin": { - "release": true, - "entry": { - "core": "./src/index.ts", - "server": "./src/server.ts" - }, - "serverCommand": [ - "com.blocksuite.bookmark-block.get-bookmark-data-by-link" - ] - }, - "scripts": { - "dev": "af dev", - "build": "af build" - }, - "dependencies": { - "@affine/component": "workspace:*", - "@affine/sdk": "workspace:*", - "@blocksuite/icons": "^2.1.33", - "foxact": "^0.2.20", - "link-preview-js": "^3.0.5" - }, - "devDependencies": { - "@affine/plugin-cli": "workspace:*" - } -} diff --git a/plugins/bookmark/project.json b/plugins/bookmark/project.json deleted file mode 100644 index bbed908f6b..0000000000 --- a/plugins/bookmark/project.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "@affine/bookmark-plugin", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "namedInputs": { - "default": [ - "{projectRoot}/**/*", - "{workspaceRoot}/packages/plugin-cli/**/*", - "sharedGlobals" - ] - }, - "targets": { - "build": { - "executor": "nx:run-script", - "options": { - "script": "build" - }, - "dependsOn": ["^build"], - "inputs": ["default"], - "outputs": [ - "{workspaceRoot}/apps/core/public/plugins/bookmark", - "{workspaceRoot}/apps/electron/dist/plugins/bookmark" - ] - } - }, - "tags": ["plugin"] -} diff --git a/plugins/bookmark/src/index.ts b/plugins/bookmark/src/index.ts deleted file mode 100644 index c143005606..0000000000 --- a/plugins/bookmark/src/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { PluginContext } from '@affine/sdk/entry'; -import { createElement } from 'react'; -import { createRoot } from 'react-dom/client'; - -import { App } from './app'; - -export const entry = (context: PluginContext) => { - console.log('register'); - - context.register('editor', (div, editor) => { - const root = createRoot(div); - root.render(createElement(App, { page: editor.page })); - return () => { - root.unmount(); - }; - }); - - return () => { - console.log('unregister'); - }; -}; diff --git a/plugins/bookmark/src/server.ts b/plugins/bookmark/src/server.ts deleted file mode 100644 index f0bc9a360c..0000000000 --- a/plugins/bookmark/src/server.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type { ServerContext } from '@affine/sdk/server'; -import { getLinkPreview } from 'link-preview-js'; - -type MetaData = { - title?: string; - description?: string; - icon?: string; - image?: string; - [x: string]: string | string[] | undefined; -}; - -export interface PreviewType { - url: string; - title: string; - siteName: string | undefined; - description: string | undefined; - mediaType: string; - contentType: string | undefined; - images: string[]; - videos: { - url: string | undefined; - secureUrl: string | null | undefined; - type: string | null | undefined; - width: string | undefined; - height: string | undefined; - }[]; - favicons: string[]; -} - -export const entry = (context: ServerContext) => { - context.registerCommand( - 'com.blocksuite.bookmark-block.get-bookmark-data-by-link', - async (url: string): Promise => { - const previewData = (await getLinkPreview(url, { - timeout: 6000, - headers: { - 'user-agent': 'googlebot', - }, - followRedirects: 'follow', - }).catch(() => { - return { - title: '', - siteName: '', - description: '', - images: [], - videos: [], - contentType: `text/html`, - favicons: [], - }; - })) as PreviewType; - - return { - title: previewData.title, - description: previewData.description, - icon: previewData.favicons[0], - image: previewData.images[0], - }; - } - ); - return () => { - context.unregisterCommand( - 'com.blocksuite.bookmark-block.get-bookmark-data-by-link' - ); - }; -}; diff --git a/plugins/bookmark/tsconfig.json b/plugins/bookmark/tsconfig.json deleted file mode 100644 index 88ac2ab9f9..0000000000 --- a/plugins/bookmark/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "include": ["./src"], - "compilerOptions": { - "noEmit": false, - "outDir": "lib", - "jsx": "preserve" - }, - "references": [ - { - "path": "../../packages/sdk" - }, - { - "path": "../../packages/component" - } - ] -} diff --git a/tests/affine-plugin/e2e/basic.spec.ts b/tests/affine-plugin/e2e/basic.spec.ts index b524670421..d2fa6de3a1 100644 --- a/tests/affine-plugin/e2e/basic.spec.ts +++ b/tests/affine-plugin/e2e/basic.spec.ts @@ -22,7 +22,6 @@ test('plugin should exist', async ({ page }) => { ); }); const plugins = [ - '@affine/bookmark-plugin', '@affine/copilot-plugin', '@affine/hello-world-plugin', '@affine/image-preview-plugin', diff --git a/tsconfig.json b/tsconfig.json index 815e2c3170..ba9012c701 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -119,9 +119,6 @@ { "path": "./packages/sdk" }, - { - "path": "./plugins/bookmark" - }, { "path": "./plugins/copilot" }, diff --git a/yarn.lock b/yarn.lock index 3f8bc89628..14d29df7fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -146,19 +146,6 @@ __metadata: languageName: unknown linkType: soft -"@affine/bookmark-plugin@workspace:*, @affine/bookmark-plugin@workspace:plugins/bookmark": - version: 0.0.0-use.local - resolution: "@affine/bookmark-plugin@workspace:plugins/bookmark" - dependencies: - "@affine/component": "workspace:*" - "@affine/plugin-cli": "workspace:*" - "@affine/sdk": "workspace:*" - "@blocksuite/icons": ^2.1.33 - foxact: ^0.2.20 - link-preview-js: ^3.0.5 - languageName: unknown - linkType: soft - "@affine/cli@workspace:*, @affine/cli@workspace:packages/cli": version: 0.0.0-use.local resolution: "@affine/cli@workspace:packages/cli" @@ -368,7 +355,6 @@ __metadata: resolution: "@affine/electron@workspace:apps/electron" dependencies: "@affine-test/kit": "workspace:*" - "@affine/bookmark-plugin": "workspace:*" "@affine/copilot-plugin": "workspace:*" "@affine/env": "workspace:*" "@affine/hello-world-plugin": "workspace:*"