Skip to content

Commit

Permalink
feat(nbstore): integrated new workspace engine
Browse files Browse the repository at this point in the history
  • Loading branch information
EYHN committed Jan 3, 2025
1 parent 3e2cbdd commit dd2a68e
Show file tree
Hide file tree
Showing 63 changed files with 848 additions and 483 deletions.
28 changes: 26 additions & 2 deletions packages/frontend/apps/electron-renderer/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,21 @@ import {
configureDesktopWorkbenchModule,
WorkbenchService,
} from '@affine/core/modules/workbench';
import { WorkspacesService } from '@affine/core/modules/workspace';
import {
WorkspaceEngineWorkerProvider,
WorkspacesService,
} from '@affine/core/modules/workspace';
import {
configureBrowserWorkspaceFlavours,
configureSqliteWorkspaceEngineStorageProvider,
} from '@affine/core/modules/workspace-engine';
import createEmotionCache from '@affine/core/utils/create-emotion-cache';
import { apis, events } from '@affine/electron-api';
import { connectWebWorker } from '@affine/electron-api/web-worker';
import { WorkerClient } from '@affine/nbstore/worker/client';
import { CacheProvider } from '@emotion/react';
import { Framework, FrameworkRoot, getCurrentStore } from '@toeverything/infra';
import { OpClient } from '@toeverything/infra/op';
import { Suspense } from 'react';
import { RouterProvider } from 'react-router-dom';

Expand Down Expand Up @@ -78,7 +84,25 @@ configureAppTabsHeaderModule(framework);
configureFindInPageModule(framework);
configureDesktopApiModule(framework);
configureSpellCheckSettingModule(framework);

framework.impl(WorkspaceEngineWorkerProvider, {
openWorker(options) {
const worker = new Worker(
new URL(
/* webpackChunkName: "nbstore-worker" */ './worker.ts',
import.meta.url
)
);
const electronApiCleanup = connectWebWorker(worker);
const client = new WorkerClient(new OpClient(worker), options);
return {
client,
dispose: () => {
worker.terminate();
electronApiCleanup();
},
};
},
});
framework.impl(PopupWindowProvider, p => {
const apis = p.get(DesktopApiService).api;
return {
Expand Down
5 changes: 5 additions & 0 deletions packages/frontend/apps/electron-renderer/src/setup.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import '@affine/core/bootstrap/electron';
import '@affine/component/theme';
import './global.css';

import { apis } from '@affine/electron-api';
import { bindNativeDBApis } from '@affine/nbstore/sqlite';

bindNativeDBApis(apis!.nbstore);
17 changes: 17 additions & 0 deletions packages/frontend/apps/electron-renderer/src/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import '@affine/core/bootstrap/electron';

import { getElectronAPIs } from '@affine/electron-api/web-worker';
import { bindNativeDBApis } from '@affine/nbstore/sqlite';
import {
WorkerConsumer,
type WorkerOps,
} from '@affine/nbstore/worker/consumer';
import { type MessageCommunicapable, OpConsumer } from '@toeverything/infra/op';

const electronAPIs = getElectronAPIs();

bindNativeDBApis(electronAPIs.nbstore);

const consumer = new OpConsumer<WorkerOps>(globalThis as MessageCommunicapable);

new WorkerConsumer(consumer);
1 change: 1 addition & 0 deletions packages/frontend/apps/ios/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^6.28.0",
"async-call-rpc": "^6.4.2",
"yjs": "^13.6.21"
},
"devDependencies": {
Expand Down
54 changes: 53 additions & 1 deletion packages/frontend/apps/ios/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ import { PopupWindowProvider } from '@affine/core/modules/url';
import { ClientSchemeProvider } from '@affine/core/modules/url/providers/client-schema';
import { configureIndexedDBUserspaceStorageProvider } from '@affine/core/modules/userspace';
import { configureBrowserWorkbenchModule } from '@affine/core/modules/workbench';
import { WorkspacesService } from '@affine/core/modules/workspace';
import {
WorkspaceEngineWorkerProvider,
WorkspacesService,
} from '@affine/core/modules/workspace';
import {
configureBrowserWorkspaceFlavours,
configureIndexedDBWorkspaceEngineStorageProvider,
} from '@affine/core/modules/workspace-engine';
import { I18n } from '@affine/i18n';
import { WorkerClient } from '@affine/nbstore/worker/client';
import {
defaultBlockMarkdownAdapterMatchers,
docLinkBaseURLMiddleware,
Expand All @@ -44,6 +48,8 @@ import { Browser } from '@capacitor/browser';
import { Haptics } from '@capacitor/haptics';
import { Keyboard, KeyboardStyle } from '@capacitor/keyboard';
import { Framework, FrameworkRoot, getCurrentStore } from '@toeverything/infra';
import { OpClient } from '@toeverything/infra/op';
import { AsyncCall } from 'async-call-rpc';
import { useTheme } from 'next-themes';
import { Suspense, useEffect } from 'react';
import { RouterProvider } from 'react-router-dom';
Expand All @@ -54,6 +60,7 @@ import { ModalConfigProvider } from './modal-config';
import { Cookie } from './plugins/cookie';
import { Hashcash } from './plugins/hashcash';
import { Intelligents } from './plugins/intelligents';
import { NbStoreNativeDBApis } from './plugins/nbstore';
import { enableNavigationGesture$ } from './web-navigation-control';

const future = {
Expand All @@ -68,6 +75,51 @@ configureBrowserWorkspaceFlavours(framework);
configureIndexedDBWorkspaceEngineStorageProvider(framework);
configureIndexedDBUserspaceStorageProvider(framework);
configureMobileModules(framework);
framework.impl(WorkspaceEngineWorkerProvider, {
openWorker(options) {
const worker = new Worker(
new URL(
/* webpackChunkName: "nbstore-worker" */ './worker.ts',
import.meta.url
)
);
const { port1: nativeDBApiChannelServer, port2: nativeDBApiChannelClient } =
new MessageChannel();
AsyncCall<typeof NbStoreNativeDBApis>(NbStoreNativeDBApis, {
channel: {
on(listener) {
const f = (e: MessageEvent<any>) => {
listener(e.data);
};
nativeDBApiChannelServer.addEventListener('message', f);
return () => {
nativeDBApiChannelServer.removeEventListener('message', f);
};
},
send(data) {
nativeDBApiChannelServer.postMessage(data);
},
},
log: false,
});
nativeDBApiChannelServer.start();
worker.postMessage(
{
type: 'native-db-api-channel',
port: nativeDBApiChannelClient,
},
[nativeDBApiChannelClient]
);
const client = new WorkerClient(new OpClient(worker), options);
return {
client,
dispose: () => {
worker.terminate();
nativeDBApiChannelServer.close();
},
};
},
});
framework.impl(PopupWindowProvider, {
open: (url: string) => {
Browser.open({
Expand Down
5 changes: 5 additions & 0 deletions packages/frontend/apps/ios/src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@ import '@affine/core/bootstrap/browser';
import '@affine/component/theme';
import '@affine/core/mobile/styles/mobile.css';

import { bindNativeDBApis } from '@affine/nbstore/sqlite';

import { NbStoreNativeDBApis } from './plugins/nbstore';

bindNativeDBApis(NbStoreNativeDBApis);
// TODO(@L-Sun) Uncomment this when the `show` method implement by `@capacitor/keyboard` in ios
// import './virtual-keyboard';
40 changes: 40 additions & 0 deletions packages/frontend/apps/ios/src/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import '@affine/core/bootstrap/browser';

import { bindNativeDBApis, type NativeDBApis } from '@affine/nbstore/sqlite';
import {
WorkerConsumer,
type WorkerOps,
} from '@affine/nbstore/worker/consumer';
import { type MessageCommunicapable, OpConsumer } from '@toeverything/infra/op';
import { AsyncCall } from 'async-call-rpc';

globalThis.addEventListener('message', e => {
if (e.data.type === 'native-db-api-channel') {
const port = e.ports[0] as MessagePort;
const rpc = AsyncCall<NativeDBApis>(
{},
{
channel: {
on(listener) {
const f = (e: MessageEvent<any>) => {
listener(e.data);
};
port.addEventListener('message', f);
return () => {
port.removeEventListener('message', f);
};
},
send(data) {
port.postMessage(data);
},
},
}
);
bindNativeDBApis(rpc);
port.start();
}
});

const consumer = new OpConsumer<WorkerOps>(globalThis as MessageCommunicapable);

new WorkerConsumer(consumer);
20 changes: 20 additions & 0 deletions packages/frontend/apps/mobile/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ import { configureLocalStorageStateStorageImpls } from '@affine/core/modules/sto
import { PopupWindowProvider } from '@affine/core/modules/url';
import { configureIndexedDBUserspaceStorageProvider } from '@affine/core/modules/userspace';
import { configureBrowserWorkbenchModule } from '@affine/core/modules/workbench';
import { WorkspaceEngineWorkerProvider } from '@affine/core/modules/workspace';
import {
configureBrowserWorkspaceFlavours,
configureIndexedDBWorkspaceEngineStorageProvider,
} from '@affine/core/modules/workspace-engine';
import { WorkerClient } from '@affine/nbstore/worker/client';
import { Framework, FrameworkRoot, getCurrentStore } from '@toeverything/infra';
import { OpClient } from '@toeverything/infra/op';
import { Suspense } from 'react';
import { RouterProvider } from 'react-router-dom';

Expand All @@ -30,6 +33,23 @@ configureBrowserWorkspaceFlavours(framework);
configureIndexedDBWorkspaceEngineStorageProvider(framework);
configureIndexedDBUserspaceStorageProvider(framework);
configureMobileModules(framework);
framework.impl(WorkspaceEngineWorkerProvider, {
openWorker(options) {
const worker = new Worker(
new URL(
/* webpackChunkName: "nbstore-worker" */ './worker.ts',
import.meta.url
)
);
const client = new WorkerClient(new OpClient(worker), options);
return {
client,
dispose: () => {
worker.terminate();
},
};
},
});
framework.impl(PopupWindowProvider, {
open: (target: string) => {
const targetUrl = new URL(target);
Expand Down
11 changes: 11 additions & 0 deletions packages/frontend/apps/mobile/src/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '@affine/core/bootstrap/browser';

import {
WorkerConsumer,
type WorkerOps,
} from '@affine/nbstore/worker/consumer';
import { type MessageCommunicapable, OpConsumer } from '@toeverything/infra/op';

const consumer = new OpConsumer<WorkerOps>(globalThis as MessageCommunicapable);

new WorkerConsumer(consumer);
1 change: 1 addition & 0 deletions packages/frontend/apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@affine/component": "workspace:*",
"@affine/core": "workspace:*",
"@affine/i18n": "workspace:*",
"@affine/nbstore": "workspace:*",
"@emotion/react": "^11.14.0",
"@sentry/react": "^8.44.0",
"react": "^19.0.0",
Expand Down
20 changes: 20 additions & 0 deletions packages/frontend/apps/web/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import { configureLocalStorageStateStorageImpls } from '@affine/core/modules/sto
import { PopupWindowProvider } from '@affine/core/modules/url';
import { configureIndexedDBUserspaceStorageProvider } from '@affine/core/modules/userspace';
import { configureBrowserWorkbenchModule } from '@affine/core/modules/workbench';
import { WorkspaceEngineWorkerProvider } from '@affine/core/modules/workspace';
import {
configureBrowserWorkspaceFlavours,
configureIndexedDBWorkspaceEngineStorageProvider,
} from '@affine/core/modules/workspace-engine';
import createEmotionCache from '@affine/core/utils/create-emotion-cache';
import { WorkerClient } from '@affine/nbstore/worker/client';
import { CacheProvider } from '@emotion/react';
import { Framework, FrameworkRoot, getCurrentStore } from '@toeverything/infra';
import { OpClient } from '@toeverything/infra/op';
import { Suspense } from 'react';
import { RouterProvider } from 'react-router-dom';

Expand All @@ -32,6 +35,23 @@ configureLocalStorageStateStorageImpls(framework);
configureBrowserWorkspaceFlavours(framework);
configureIndexedDBWorkspaceEngineStorageProvider(framework);
configureIndexedDBUserspaceStorageProvider(framework);
framework.impl(WorkspaceEngineWorkerProvider, {
openWorker(options) {
const worker = new Worker(
new URL(
/* webpackChunkName: "nbstore-worker" */ './worker.ts',
import.meta.url
)
);
const client = new WorkerClient(new OpClient(worker), options);
return {
client,
dispose: () => {
worker.terminate();
},
};
},
});
framework.impl(PopupWindowProvider, {
open: (target: string) => {
const targetUrl = new URL(target);
Expand Down
11 changes: 11 additions & 0 deletions packages/frontend/apps/web/src/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '@affine/core/bootstrap/browser';

import {
WorkerConsumer,
type WorkerOps,
} from '@affine/nbstore/worker/consumer';
import { type MessageCommunicapable, OpConsumer } from '@toeverything/infra/op';

const consumer = new OpConsumer<WorkerOps>(globalThis as MessageCommunicapable);

new WorkerConsumer(consumer);
7 changes: 6 additions & 1 deletion packages/frontend/apps/web/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@
"rootDir": "./src"
},
"include": ["./src"],
"references": [{ "path": "../../core" }]
"references": [
{ "path": "../../core" },
{
"path": "../../../common/nbstore"
}
]
}
1 change: 1 addition & 0 deletions packages/frontend/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@affine/env": "workspace:*",
"@affine/graphql": "workspace:*",
"@affine/i18n": "workspace:*",
"@affine/nbstore": "workspace:*",
"@affine/templates": "workspace:*",
"@affine/track": "workspace:*",
"@blocksuite/affine": "workspace:*",
Expand Down
10 changes: 4 additions & 6 deletions packages/frontend/core/src/bootstrap/polyfill/browser.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { polyfillDispose } from './dispose';
import { polyfillIteratorHelpers } from './iterator-helpers';
import { polyfillPromise } from './promise-with-resolvers';
import './dispose';
import './iterator-helpers';
import './promise-with-resolvers';

import { polyfillEventLoop } from './request-idle-callback';
import { polyfillResizeObserver } from './resize-observer';

polyfillResizeObserver();
polyfillEventLoop();
await polyfillPromise();
await polyfillDispose();
await polyfillIteratorHelpers();
10 changes: 2 additions & 8 deletions packages/frontend/core/src/bootstrap/polyfill/dispose.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,2 @@
export async function polyfillDispose() {
if (typeof Symbol.dispose !== 'symbol') {
// @ts-expect-error ignore
await import('core-js/modules/esnext.symbol.async-dispose');
// @ts-expect-error ignore
await import('core-js/modules/esnext.symbol.dispose');
}
}
import 'core-js/modules/esnext.symbol.async-dispose';
import 'core-js/modules/esnext.symbol.dispose';
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
export async function polyfillIteratorHelpers() {
if (typeof globalThis['Iterator'] !== 'function') {
// @ts-expect-error ignore
// https://github.com/zloirock/core-js/blob/master/packages/core-js/proposals/iterator-helpers-stage-3.js
await import('core-js/proposals/iterator-helpers-stage-3');
}
}
import 'core-js/proposals/iterator-helpers-stage-3';
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
export async function polyfillPromise() {
if (typeof Promise.withResolvers !== 'function') {
// @ts-expect-error ignore
await import('core-js/features/promise/with-resolvers');
}
}
import 'core-js/features/promise/with-resolvers';
Loading

0 comments on commit dd2a68e

Please sign in to comment.