mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 13:01:59 +03:00
feat: add infra code (#2718)
This commit is contained in:
parent
4958d096b0
commit
f3fd5ff76b
@ -1,10 +1,19 @@
|
||||
import type {
|
||||
DBHandlerManager,
|
||||
DebugHandlerManager,
|
||||
DialogHandlerManager,
|
||||
ExportHandlerManager,
|
||||
UIHandlerManager,
|
||||
UpdaterHandlerManager,
|
||||
WorkspaceHandlerManager,
|
||||
} from '@toeverything/infra';
|
||||
import type { HandlerManager, PrimitiveHandlers } from '@toeverything/infra';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import { dbHandlers } from './db';
|
||||
import { dialogHandlers } from './dialog';
|
||||
import { exportHandlers } from './export';
|
||||
import { getLogFilePath, logger, revealLogFile } from './logger';
|
||||
import type { NamespaceHandlers } from './type';
|
||||
import { uiHandlers } from './ui';
|
||||
import { updaterHandlers } from './updater';
|
||||
import { workspaceHandlers } from './workspace';
|
||||
@ -18,6 +27,26 @@ export const debugHandlers = {
|
||||
},
|
||||
};
|
||||
|
||||
type UnwrapManagerHandler<
|
||||
Manager extends HandlerManager<string, Record<string, PrimitiveHandlers>>
|
||||
> = {
|
||||
[K in keyof Manager['handlers']]: Manager['handlers'][K] extends (
|
||||
...args: infer Args
|
||||
) => Promise<infer R>
|
||||
? (event: Electron.IpcMainInvokeEvent, ...args: Args) => Promise<R>
|
||||
: never;
|
||||
};
|
||||
|
||||
type AllHandlers = {
|
||||
db: UnwrapManagerHandler<DBHandlerManager>;
|
||||
debug: UnwrapManagerHandler<DebugHandlerManager>;
|
||||
dialog: UnwrapManagerHandler<DialogHandlerManager>;
|
||||
export: UnwrapManagerHandler<ExportHandlerManager>;
|
||||
ui: UnwrapManagerHandler<UIHandlerManager>;
|
||||
updater: UnwrapManagerHandler<UpdaterHandlerManager>;
|
||||
workspace: UnwrapManagerHandler<WorkspaceHandlerManager>;
|
||||
};
|
||||
|
||||
// Note: all of these handlers will be the single-source-of-truth for the apis exposed to the renderer process
|
||||
export const allHandlers = {
|
||||
db: dbHandlers,
|
||||
@ -27,7 +56,7 @@ export const allHandlers = {
|
||||
export: exportHandlers,
|
||||
updater: updaterHandlers,
|
||||
workspace: workspaceHandlers,
|
||||
} satisfies Record<string, NamespaceHandlers>;
|
||||
} satisfies AllHandlers;
|
||||
|
||||
export const registerHandlers = () => {
|
||||
// TODO: listen to namespace instead of individual event types
|
||||
|
@ -35,6 +35,7 @@
|
||||
"@electron-forge/maker-zip": "^6.1.1",
|
||||
"@electron-forge/shared-types": "^6.1.1",
|
||||
"@electron/remote": "2.0.9",
|
||||
"@toeverything/infra": "workspace:*",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"cross-env": "7.0.3",
|
||||
|
@ -46,7 +46,7 @@ export const config = () => {
|
||||
bundle: true,
|
||||
target: `node${NODE_MAJOR_VERSION}`,
|
||||
platform: 'node',
|
||||
external: ['electron', 'yjs', 'electron-updater'],
|
||||
external: ['electron', 'yjs', 'electron-updater', '@toeverything/infra'],
|
||||
define: define,
|
||||
format: 'cjs',
|
||||
loader: {
|
||||
|
@ -26,6 +26,9 @@
|
||||
{
|
||||
"path": "../../packages/env"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/infra"
|
||||
},
|
||||
{ "path": "../../tests/kit" }
|
||||
],
|
||||
"ts-node": {
|
||||
|
@ -112,6 +112,7 @@ const nextConfig = {
|
||||
'@affine/copilot',
|
||||
'@toeverything/hooks',
|
||||
'@toeverything/y-indexeddb',
|
||||
'@toeverything/infra',
|
||||
'@toeverything/plugin-infra',
|
||||
],
|
||||
publicRuntimeConfig: {
|
||||
|
@ -35,6 +35,7 @@
|
||||
"@react-hookz/web": "^23.0.1",
|
||||
"@sentry/nextjs": "^7.54.0",
|
||||
"@toeverything/hooks": "workspace:*",
|
||||
"@toeverything/infra": "workspace:*",
|
||||
"@toeverything/plugin-infra": "workspace:*",
|
||||
"cmdk": "^0.2.0",
|
||||
"css-spring": "^4.1.0",
|
||||
|
@ -50,10 +50,8 @@ rootWorkspacesMetadataAtom.onMount = setAtom => {
|
||||
}, 0);
|
||||
|
||||
if (environment.isDesktop) {
|
||||
// @ts-expect-error
|
||||
window.apis?.workspace.list().then(workspaceIDs => {
|
||||
if (abortController.signal.aborted) return;
|
||||
// @ts-expect-error
|
||||
const newMetadata = workspaceIDs.map(w => ({
|
||||
id: w[0],
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
@ -61,7 +59,6 @@ rootWorkspacesMetadataAtom.onMount = setAtom => {
|
||||
setAtom(metadata => {
|
||||
return [
|
||||
...metadata,
|
||||
// @ts-expect-error
|
||||
...newMetadata.filter(m => !metadata.find(m2 => m2.id === m.id)),
|
||||
];
|
||||
});
|
||||
|
@ -122,7 +122,6 @@ const useDefaultDBLocation = () => {
|
||||
const [defaultDBLocation, setDefaultDBLocation] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
// @ts-expect-error
|
||||
window.apis?.db.getDefaultStorageLocation().then(dir => {
|
||||
setDefaultDBLocation(dir);
|
||||
});
|
||||
|
@ -27,7 +27,6 @@ const useShowOpenDBFile = (workspaceId: string) => {
|
||||
const [show, setShow] = useState(false);
|
||||
useEffect(() => {
|
||||
if (window.apis && window.events && environment.isDesktop) {
|
||||
// @ts-expect-error
|
||||
window.apis.workspace.getMeta(workspaceId).then(meta => {
|
||||
setShow(!!meta.secondaryDBPath);
|
||||
});
|
||||
|
5
packages/env/package.json
vendored
5
packages/env/package.json
vendored
@ -4,7 +4,6 @@
|
||||
"main": "./src/index.ts",
|
||||
"module": "./src/index.ts",
|
||||
"devDependencies": {
|
||||
"@affine/templates": "workspace:*",
|
||||
"@blocksuite/global": "0.0.0-20230606130340-805f430b-nightly",
|
||||
"next": "=13.4.2",
|
||||
"react": "18.3.0-canary-16d053d59-20230506",
|
||||
@ -21,7 +20,9 @@
|
||||
"./blocksuite": "./src/blocksuite/index.ts"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@blocksuite/global": "0.0.0-20230409084303-221991d4-nightly"
|
||||
"@affine/templates": "workspace:*",
|
||||
"@blocksuite/global": "0.0.0-20230409084303-221991d4-nightly",
|
||||
"@toeverything/infra": "workspace:*"
|
||||
},
|
||||
"dependencies": {
|
||||
"lit": "^2.7.5"
|
||||
|
31
packages/env/src/config.ts
vendored
31
packages/env/src/config.ts
vendored
@ -1,16 +1,45 @@
|
||||
/// <reference types="@blocksuite/global" />
|
||||
import { assertEquals } from '@blocksuite/global/utils';
|
||||
import type {
|
||||
DBHandlerManager,
|
||||
DebugHandlerManager,
|
||||
DialogHandlerManager,
|
||||
ExportHandlerManager,
|
||||
HandlerManager,
|
||||
PrimitiveHandlers,
|
||||
UIHandlerManager,
|
||||
UpdaterHandlerManager,
|
||||
WorkspaceHandlerManager,
|
||||
} from '@toeverything/infra';
|
||||
import getConfig from 'next/config';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { UaHelper } from './ua-helper';
|
||||
|
||||
type UnwrapManagerHandler<
|
||||
Manager extends HandlerManager<string, Record<string, PrimitiveHandlers>>
|
||||
> = {
|
||||
[K in keyof Manager['handlers']]: Manager['handlers'][K] extends (
|
||||
...args: infer Args
|
||||
) => Promise<infer R>
|
||||
? (...args: Args) => Promise<R>
|
||||
: never;
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
appInfo: {
|
||||
electron: boolean;
|
||||
};
|
||||
apis: any;
|
||||
apis: {
|
||||
db: UnwrapManagerHandler<DBHandlerManager>;
|
||||
debug: UnwrapManagerHandler<DebugHandlerManager>;
|
||||
dialog: UnwrapManagerHandler<DialogHandlerManager>;
|
||||
export: UnwrapManagerHandler<ExportHandlerManager>;
|
||||
ui: UnwrapManagerHandler<UIHandlerManager>;
|
||||
updater: UnwrapManagerHandler<UpdaterHandlerManager>;
|
||||
workspace: UnwrapManagerHandler<WorkspaceHandlerManager>;
|
||||
};
|
||||
events: any;
|
||||
}
|
||||
}
|
||||
|
7
packages/env/tsconfig.json
vendored
7
packages/env/tsconfig.json
vendored
@ -5,5 +5,10 @@
|
||||
"composite": true,
|
||||
"noEmit": false,
|
||||
"outDir": "lib"
|
||||
}
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "../infra"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
31
packages/infra/package.json
Normal file
31
packages/infra/package.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "@toeverything/infra",
|
||||
"main": "./src/index.ts",
|
||||
"module": "./src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"publishConfig": {
|
||||
"module": "./dist/index.mjs",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"dev": "vite build --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^4.3.9",
|
||||
"vite-plugin-dts": "^2.3.0"
|
||||
}
|
||||
}
|
105
packages/infra/src/handler.ts
Normal file
105
packages/infra/src/handler.ts
Normal file
@ -0,0 +1,105 @@
|
||||
export interface WorkspaceMeta {
|
||||
id: string;
|
||||
mainDBPath: string;
|
||||
secondaryDBPath?: string; // assume there will be only one
|
||||
}
|
||||
|
||||
export type PrimitiveHandlers = (...args: any[]) => Promise<any>;
|
||||
type TODO = any;
|
||||
|
||||
export abstract class HandlerManager<
|
||||
Namespace extends string,
|
||||
Handlers extends Record<string, PrimitiveHandlers>
|
||||
> {
|
||||
abstract readonly app: TODO;
|
||||
abstract readonly namespace: Namespace;
|
||||
abstract readonly handlers: Handlers;
|
||||
}
|
||||
|
||||
type DBHandlers = {
|
||||
getDocAsUpdates: (id: string) => Promise<Uint8Array>;
|
||||
applyDocUpdate: (id: string, update: Uint8Array) => Promise<void>;
|
||||
addBlob: (
|
||||
workspaceId: string,
|
||||
key: string,
|
||||
data: Uint8Array
|
||||
) => Promise<void>;
|
||||
getBlob: (workspaceId: string, key: string) => Promise<any>;
|
||||
deleteBlob: (workspaceId: string, key: string) => Promise<void>;
|
||||
getBlobKeys: (workspaceId: string) => Promise<any>;
|
||||
getDefaultStorageLocation: () => Promise<string>;
|
||||
};
|
||||
|
||||
export abstract class DBHandlerManager extends HandlerManager<
|
||||
'db',
|
||||
DBHandlers
|
||||
> {}
|
||||
|
||||
type DebugHandlers = {
|
||||
revealLogFile: () => Promise<string>;
|
||||
logFilePath: () => Promise<string>;
|
||||
};
|
||||
|
||||
export abstract class DebugHandlerManager extends HandlerManager<
|
||||
'debug',
|
||||
DebugHandlers
|
||||
> {}
|
||||
|
||||
type DialogHandlers = {
|
||||
revealDBFile: (workspaceId: string) => Promise<any>;
|
||||
loadDBFile: () => Promise<any>;
|
||||
saveDBFileAs: (workspaceId: string) => Promise<any>;
|
||||
moveDBFile: (workspaceId: string, dbFileLocation?: string) => Promise<any>;
|
||||
selectDBFileLocation: () => Promise<any>;
|
||||
setFakeDialogResult: (result: any) => Promise<any>;
|
||||
};
|
||||
|
||||
export abstract class DialogHandlerManager extends HandlerManager<
|
||||
'dialog',
|
||||
DialogHandlers
|
||||
> {}
|
||||
|
||||
type UIHandlers = {
|
||||
handleThemeChange: (theme: 'system' | 'light' | 'dark') => Promise<any>;
|
||||
handleSidebarVisibilityChange: (visible: boolean) => Promise<any>;
|
||||
handleMinimizeApp: () => Promise<any>;
|
||||
handleMaximizeApp: () => Promise<any>;
|
||||
handleCloseApp: () => Promise<any>;
|
||||
getGoogleOauthCode: () => Promise<any>;
|
||||
};
|
||||
|
||||
export abstract class UIHandlerManager extends HandlerManager<
|
||||
'ui',
|
||||
UIHandlers
|
||||
> {}
|
||||
|
||||
type ExportHandlers = {
|
||||
savePDFFileAs: (title: string) => Promise<any>;
|
||||
};
|
||||
|
||||
export abstract class ExportHandlerManager extends HandlerManager<
|
||||
'export',
|
||||
ExportHandlers
|
||||
> {}
|
||||
|
||||
type UpdaterHandlers = {
|
||||
currentVersion: () => Promise<any>;
|
||||
quitAndInstall: () => Promise<any>;
|
||||
checkForUpdatesAndNotify: () => Promise<any>;
|
||||
};
|
||||
|
||||
export abstract class UpdaterHandlerManager extends HandlerManager<
|
||||
'updater',
|
||||
UpdaterHandlers
|
||||
> {}
|
||||
|
||||
type WorkspaceHandlers = {
|
||||
list: () => Promise<[workspaceId: string, meta: WorkspaceMeta][]>;
|
||||
delete: (id: string) => Promise<void>;
|
||||
getMeta: (id: string) => Promise<WorkspaceMeta>;
|
||||
};
|
||||
|
||||
export abstract class WorkspaceHandlerManager extends HandlerManager<
|
||||
'workspace',
|
||||
WorkspaceHandlers
|
||||
> {}
|
1
packages/infra/src/index.ts
Normal file
1
packages/infra/src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './handler';
|
14
packages/infra/tsconfig.json
Normal file
14
packages/infra/tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["./src"],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"noEmit": false,
|
||||
"outDir": "lib"
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
}
|
||||
]
|
||||
}
|
12
packages/infra/tsconfig.node.json
Normal file
12
packages/infra/tsconfig.node.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"outDir": "lib",
|
||||
"noEmit": false
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
24
packages/infra/vite.config.ts
Normal file
24
packages/infra/vite.config.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
import { fileURLToPath } from 'url';
|
||||
import dts from 'vite-plugin-dts';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
const root = fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
lib: {
|
||||
entry: {
|
||||
index: resolve(root, 'src/index.ts'),
|
||||
},
|
||||
formats: ['es', 'cjs'],
|
||||
name: 'AffineInfra',
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
dts({
|
||||
insertTypesEntry: true,
|
||||
}),
|
||||
],
|
||||
});
|
@ -102,11 +102,9 @@ export const CRUD: WorkspaceCRUD<WorkspaceFlavour.LOCAL> = {
|
||||
|
||||
// workspaces in desktop
|
||||
if (window.apis && environment.isDesktop) {
|
||||
// @ts-expect-error
|
||||
const desktopIds = (await window.apis.workspace.list()).map(([id]) => id);
|
||||
// the ids maybe a subset of the local storage
|
||||
const moreWorkspaces = desktopIds.filter(
|
||||
// @ts-expect-error
|
||||
id => !allWorkspaceIDs.includes(id)
|
||||
);
|
||||
allWorkspaceIDs = [...allWorkspaceIDs, ...moreWorkspaces];
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
packages=(
|
||||
"y-indexeddb"
|
||||
"infra"
|
||||
)
|
||||
|
||||
for package in "${packages[@]}"; do
|
||||
|
@ -28,7 +28,7 @@
|
||||
"@affine/i18n/hooks": ["./packages/i18n/src/i18n-generated"],
|
||||
"@affine/debug": ["./packages/debug"],
|
||||
"@affine/jotai": ["./packages/jotai"],
|
||||
"@affine/env": ["./packages/env"],
|
||||
"@affine/env": ["./packages/env/src"],
|
||||
"@affine/env/*": ["./packages/env/src/*"],
|
||||
"@affine/utils": ["./packages/utils"],
|
||||
"@affine/workspace/*": ["./packages/workspace/src/*"],
|
||||
@ -41,6 +41,7 @@
|
||||
],
|
||||
"@affine-test/kit/*": ["./tests/kit/*"],
|
||||
"@affine-test/fixtures/*": ["./tests/fixtures/*"],
|
||||
"@toeverything/infra": ["./packages/infra/src"],
|
||||
"@toeverything/y-indexeddb": ["./packages/y-indexeddb/src"],
|
||||
"@toeverything/hooks/*": ["./packages/hooks/src/*"],
|
||||
"@toeverything/plugin-infra": ["./packages/plugin-infra/src"],
|
||||
@ -63,6 +64,9 @@
|
||||
{
|
||||
"path": "./apps/server"
|
||||
},
|
||||
{
|
||||
"path": "./packages/infra"
|
||||
},
|
||||
{
|
||||
"path": "./packages/component"
|
||||
},
|
||||
|
14
yarn.lock
14
yarn.lock
@ -158,6 +158,7 @@ __metadata:
|
||||
"@electron-forge/maker-zip": ^6.1.1
|
||||
"@electron-forge/shared-types": ^6.1.1
|
||||
"@electron/remote": 2.0.9
|
||||
"@toeverything/infra": "workspace:*"
|
||||
"@types/fs-extra": ^11.0.1
|
||||
"@types/uuid": ^9.0.1
|
||||
cheerio: ^1.0.0-rc.12
|
||||
@ -188,7 +189,6 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/env@workspace:packages/env"
|
||||
dependencies:
|
||||
"@affine/templates": "workspace:*"
|
||||
"@blocksuite/global": 0.0.0-20230606130340-805f430b-nightly
|
||||
lit: ^2.7.5
|
||||
next: =13.4.2
|
||||
@ -196,7 +196,9 @@ __metadata:
|
||||
react-dom: 18.3.0-canary-16d053d59-20230506
|
||||
zod: ^3.21.4
|
||||
peerDependencies:
|
||||
"@affine/templates": "workspace:*"
|
||||
"@blocksuite/global": 0.0.0-20230409084303-221991d4-nightly
|
||||
"@toeverything/infra": "workspace:*"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@ -389,6 +391,7 @@ __metadata:
|
||||
"@swc-jotai/debug-label": ^0.0.10
|
||||
"@swc-jotai/react-refresh": ^0.0.8
|
||||
"@toeverything/hooks": "workspace:*"
|
||||
"@toeverything/infra": "workspace:*"
|
||||
"@toeverything/plugin-infra": "workspace:*"
|
||||
"@types/react": ^18.2.6
|
||||
"@types/react-dom": ^18.2.4
|
||||
@ -9204,6 +9207,15 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@toeverything/infra@workspace:*, @toeverything/infra@workspace:packages/infra":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@toeverything/infra@workspace:packages/infra"
|
||||
dependencies:
|
||||
vite: ^4.3.9
|
||||
vite-plugin-dts: ^2.3.0
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@toeverything/plugin-infra@workspace:*, @toeverything/plugin-infra@workspace:packages/plugin-infra":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@toeverything/plugin-infra@workspace:packages/plugin-infra"
|
||||
|
Loading…
Reference in New Issue
Block a user