mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
feat: move data center to root
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { signInWithGoogle } from '@affine/datacenter';
|
import { getDataCenter } from '@affine/datacenter';
|
||||||
import { styled } from '@/styles';
|
import { styled } from '@/styles';
|
||||||
import { Button } from '@/ui/button';
|
import { Button } from '@/ui/button';
|
||||||
import { useModal } from '@/providers/global-modal-provider';
|
import { useModal } from '@/providers/global-modal-provider';
|
||||||
@@ -9,7 +9,8 @@ export const GoogleLoginButton = () => {
|
|||||||
return (
|
return (
|
||||||
<StyledGoogleButton
|
<StyledGoogleButton
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
signInWithGoogle()
|
getDataCenter()
|
||||||
|
.then(dc => dc.apis.signInWithGoogle())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
triggerLoginModal();
|
triggerLoginModal();
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
import { createContext, MutableRefObject, useContext } from 'react';
|
import { createContext, MutableRefObject, useContext } from 'react';
|
||||||
import type { Workspace } from '@affine/datacenter';
|
import type { Workspace } from '@affine/datacenter';
|
||||||
import { AccessTokenMessage } from '@affine/datacenter';
|
|
||||||
import type {
|
import type {
|
||||||
Page as StorePage,
|
Page as StorePage,
|
||||||
Workspace as StoreWorkspace,
|
Workspace as StoreWorkspace,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
import type { EditorContainer } from '@blocksuite/editor';
|
import type { EditorContainer } from '@blocksuite/editor';
|
||||||
export type LoadWorkspaceHandler = (
|
export type LoadWorkspaceHandler = (
|
||||||
workspaceId: string,
|
workspaceId: string
|
||||||
user?: AccessTokenMessage | null
|
// user?: AccessTokenMessage | null
|
||||||
) => Promise<StoreWorkspace | null> | null;
|
) => Promise<StoreWorkspace | null> | null;
|
||||||
export type CreateEditorHandler = (page: StorePage) => EditorContainer | null;
|
export type CreateEditorHandler = (page: StorePage) => EditorContainer | null;
|
||||||
|
|
||||||
export interface AppStateValue {
|
export interface AppStateValue {
|
||||||
user: AccessTokenMessage | null;
|
// user: AccessTokenMessage | null;
|
||||||
workspacesMeta: Workspace[];
|
workspacesMeta: Workspace[];
|
||||||
|
|
||||||
currentWorkspaceId: string;
|
currentWorkspaceId: string;
|
||||||
@@ -39,7 +38,7 @@ export interface AppStateContext extends AppStateValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const AppState = createContext<AppStateContext>({
|
export const AppState = createContext<AppStateContext>({
|
||||||
user: null,
|
// user: null,
|
||||||
workspacesMeta: [],
|
workspacesMeta: [],
|
||||||
|
|
||||||
currentWorkspaceId: '',
|
currentWorkspaceId: '',
|
||||||
|
|||||||
17
packages/data-center/src/apis/index.ts
Normal file
17
packages/data-center/src/apis/index.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export { token } from './token.js';
|
||||||
|
export type { Callback } from './token.js';
|
||||||
|
|
||||||
|
import { getAuthorizer } from './token.js';
|
||||||
|
import * as user from './user.js';
|
||||||
|
import * as workspace from './workspace.js';
|
||||||
|
|
||||||
|
export type Apis = typeof user &
|
||||||
|
typeof workspace & {
|
||||||
|
signInWithGoogle: ReturnType<typeof getAuthorizer>[0];
|
||||||
|
onAuthStateChanged: ReturnType<typeof getAuthorizer>[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getApis = (): Apis => {
|
||||||
|
const [signInWithGoogle, onAuthStateChanged] = getAuthorizer();
|
||||||
|
return { ...user, ...workspace, signInWithGoogle, onAuthStateChanged };
|
||||||
|
};
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
import { getLogger } from '../../index.js';
|
import { initializeApp } from 'firebase/app';
|
||||||
|
import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth';
|
||||||
|
import type { User } from 'firebase/auth';
|
||||||
|
|
||||||
|
import { getLogger } from '../index.js';
|
||||||
import { bareClient } from './request.js';
|
import { bareClient } from './request.js';
|
||||||
|
|
||||||
export interface AccessTokenMessage {
|
interface AccessTokenMessage {
|
||||||
create_at: number;
|
create_at: number;
|
||||||
exp: number;
|
exp: number;
|
||||||
email: string;
|
email: string;
|
||||||
@@ -133,3 +137,34 @@ class Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const token = new Token();
|
export const token = new Token();
|
||||||
|
|
||||||
|
export const getAuthorizer = () => {
|
||||||
|
const app = initializeApp({
|
||||||
|
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
|
||||||
|
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
|
||||||
|
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
|
||||||
|
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
|
||||||
|
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
|
||||||
|
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
|
||||||
|
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const firebaseAuth = getAuth(app);
|
||||||
|
|
||||||
|
const googleAuthProvider = new GoogleAuthProvider();
|
||||||
|
|
||||||
|
const signInWithGoogle = async () => {
|
||||||
|
const user = await signInWithPopup(firebaseAuth, googleAuthProvider);
|
||||||
|
const idToken = await user.user.getIdToken();
|
||||||
|
await token.initToken(idToken);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onAuthStateChanged = (callback: (user: User | null) => void) => {
|
||||||
|
firebaseAuth.onAuthStateChanged(callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
return [signInWithGoogle, onAuthStateChanged] as const;
|
||||||
|
} catch (e) {
|
||||||
|
return [] as const;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
// TODO: temporary reference, move all api into affine provider
|
import { client } from './request.js';
|
||||||
import { client } from '../datacenter/provider/affine/request';
|
|
||||||
|
|
||||||
export interface GetUserByEmailParams {
|
export interface GetUserByEmailParams {
|
||||||
email: string;
|
email: string;
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
// TODO: temporary reference, move all api into affine provider
|
import { bareClient, client } from './request.js';
|
||||||
import { bareClient, client } from '../datacenter/provider/affine/request';
|
import type { User } from './user';
|
||||||
import { User } from './user';
|
|
||||||
|
|
||||||
export interface GetWorkspaceDetailParams {
|
export interface GetWorkspaceDetailParams {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -165,6 +164,13 @@ export async function getBlob(params: {
|
|||||||
export interface LeaveWorkspaceParams {
|
export interface LeaveWorkspaceParams {
|
||||||
id: number | string;
|
id: number | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function leaveWorkspace({ id }: LeaveWorkspaceParams) {
|
export async function leaveWorkspace({ id }: LeaveWorkspaceParams) {
|
||||||
await client.delete(`api/workspace/${id}/permission`).json();
|
await client.delete(`api/workspace/${id}/permission`).json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function downloadWorkspace(
|
||||||
|
workspaceId: string
|
||||||
|
): Promise<ArrayBuffer> {
|
||||||
|
return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer();
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import { initializeApp } from 'firebase/app';
|
|
||||||
import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth';
|
|
||||||
import type { User } from 'firebase/auth';
|
|
||||||
// TODO: temporary reference, move all api into affine provider
|
|
||||||
import { token } from './datacenter/provider/affine/token';
|
|
||||||
|
|
||||||
const app = initializeApp({
|
|
||||||
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
|
|
||||||
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
|
|
||||||
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
|
|
||||||
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
|
|
||||||
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
|
|
||||||
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
|
|
||||||
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const firebaseAuth = getAuth(app);
|
|
||||||
|
|
||||||
const googleAuthProvider = new GoogleAuthProvider();
|
|
||||||
export const signInWithGoogle = async () => {
|
|
||||||
const user = await signInWithPopup(firebaseAuth, googleAuthProvider);
|
|
||||||
const idToken = await user.user.getIdToken();
|
|
||||||
await token.initToken(idToken);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const onAuthStateChanged = (callback: (user: User | null) => void) => {
|
|
||||||
firebaseAuth.onAuthStateChanged(callback);
|
|
||||||
};
|
|
||||||
@@ -3,6 +3,7 @@ import { BlockSchema } from '@blocksuite/blocks/models';
|
|||||||
import { Workspace } from '@blocksuite/store';
|
import { Workspace } from '@blocksuite/store';
|
||||||
|
|
||||||
import { getLogger } from './index.js';
|
import { getLogger } from './index.js';
|
||||||
|
import { getApis, Apis } from './apis/index.js';
|
||||||
import { AffineProvider, BaseProvider } from './provider/index.js';
|
import { AffineProvider, BaseProvider } from './provider/index.js';
|
||||||
import { LocalProvider } from './provider/index.js';
|
import { LocalProvider } from './provider/index.js';
|
||||||
import { getKVConfigure } from './store.js';
|
import { getKVConfigure } from './store.js';
|
||||||
@@ -13,6 +14,7 @@ type GetWorkspaceParams = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class DataCenter {
|
export class DataCenter {
|
||||||
|
private readonly _apis: Apis;
|
||||||
private readonly _providers = new Map<string, typeof BaseProvider>();
|
private readonly _providers = new Map<string, typeof BaseProvider>();
|
||||||
private readonly _workspaces = new Map<string, Promise<BaseProvider>>();
|
private readonly _workspaces = new Map<string, Promise<BaseProvider>>();
|
||||||
private readonly _config;
|
private readonly _config;
|
||||||
@@ -27,11 +29,16 @@ export class DataCenter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private constructor(debug: boolean) {
|
private constructor(debug: boolean) {
|
||||||
|
this._apis = getApis();
|
||||||
this._config = getKVConfigure('sys');
|
this._config = getKVConfigure('sys');
|
||||||
this._logger = getLogger('dc');
|
this._logger = getLogger('dc');
|
||||||
this._logger.enabled = debug;
|
this._logger.enabled = debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get apis(): Readonly<Apis> {
|
||||||
|
return this._apis;
|
||||||
|
}
|
||||||
|
|
||||||
private addProvider(provider: typeof BaseProvider) {
|
private addProvider(provider: typeof BaseProvider) {
|
||||||
this._providers.set(provider.id, provider);
|
this._providers.set(provider.id, provider);
|
||||||
}
|
}
|
||||||
@@ -61,6 +68,7 @@ export class DataCenter {
|
|||||||
const provider = new Provider();
|
const provider = new Provider();
|
||||||
|
|
||||||
await provider.init({
|
await provider.init({
|
||||||
|
apis: this._apis,
|
||||||
config: getKVConfigure(id),
|
config: getKVConfigure(id),
|
||||||
debug: this._logger.enabled,
|
debug: this._logger.enabled,
|
||||||
logger: this._logger.extend(`${Provider.id}:${id}`),
|
logger: this._logger.extend(`${Provider.id}:${id}`),
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import debug from 'debug';
|
|
||||||
import { DataCenter } from './datacenter.js';
|
|
||||||
|
|
||||||
const _initializeDataCenter = () => {
|
|
||||||
let _dataCenterInstance: Promise<DataCenter>;
|
|
||||||
|
|
||||||
return (debug = true) => {
|
|
||||||
if (!_dataCenterInstance) {
|
|
||||||
_dataCenterInstance = DataCenter.init(debug);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _dataCenterInstance;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getDataCenter = _initializeDataCenter();
|
|
||||||
|
|
||||||
export function getLogger(namespace: string) {
|
|
||||||
const logger = debug(namespace);
|
|
||||||
logger.log = console.log.bind(console);
|
|
||||||
return logger;
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import { client } from './request.js';
|
|
||||||
|
|
||||||
export async function downloadWorkspace(
|
|
||||||
workspaceId: string
|
|
||||||
): Promise<ArrayBuffer> {
|
|
||||||
return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer();
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,22 @@
|
|||||||
export { signInWithGoogle, onAuthStateChanged } from './auth';
|
import debug from 'debug';
|
||||||
export * from './sdks';
|
import { DataCenter } from './datacenter.js';
|
||||||
|
|
||||||
export { getDataCenter } from './datacenter';
|
const _initializeDataCenter = () => {
|
||||||
|
let _dataCenterInstance: Promise<DataCenter>;
|
||||||
|
|
||||||
// TODO: temporary reference, move all api into affine provider
|
return (debug = true) => {
|
||||||
export { token } from './datacenter/provider/affine/token';
|
if (!_dataCenterInstance) {
|
||||||
export type { AccessTokenMessage } from './datacenter/provider/affine/token';
|
_dataCenterInstance = DataCenter.init(debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _dataCenterInstance;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getDataCenter = _initializeDataCenter();
|
||||||
|
|
||||||
|
export function getLogger(namespace: string) {
|
||||||
|
const logger = debug(namespace);
|
||||||
|
logger.log = console.log.bind(console);
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,11 +2,10 @@ import assert from 'assert';
|
|||||||
import { applyUpdate } from 'yjs';
|
import { applyUpdate } from 'yjs';
|
||||||
|
|
||||||
import type { InitialParams } from '../index.js';
|
import type { InitialParams } from '../index.js';
|
||||||
|
import { token, Callback } from '../../apis/index.js';
|
||||||
import { LocalProvider } from '../local/index.js';
|
import { LocalProvider } from '../local/index.js';
|
||||||
|
|
||||||
import { downloadWorkspace } from './apis.js';
|
|
||||||
import { WebsocketProvider } from './sync.js';
|
import { WebsocketProvider } from './sync.js';
|
||||||
import { token, Callback } from './token.js';
|
|
||||||
|
|
||||||
export class AffineProvider extends LocalProvider {
|
export class AffineProvider extends LocalProvider {
|
||||||
static id = 'affine';
|
static id = 'affine';
|
||||||
@@ -67,7 +66,7 @@ export class AffineProvider extends LocalProvider {
|
|||||||
|
|
||||||
if (workspace.room && token.isLogin) {
|
if (workspace.room && token.isLogin) {
|
||||||
try {
|
try {
|
||||||
const updates = await downloadWorkspace(workspace.room);
|
const updates = await this._apis.downloadWorkspace(workspace.room);
|
||||||
if (updates) {
|
if (updates) {
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
doc.once('update', resolve);
|
doc.once('update', resolve);
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
import type { Workspace } from '@blocksuite/store';
|
import type { Workspace } from '@blocksuite/store';
|
||||||
|
|
||||||
import type { Logger, InitialParams, ConfigStore } from './index';
|
import type { Apis, Logger, InitialParams, ConfigStore } from './index';
|
||||||
|
|
||||||
export class BaseProvider {
|
export class BaseProvider {
|
||||||
static id = 'base';
|
static id = 'base';
|
||||||
protected _config!: ConfigStore;
|
protected _apis!: Readonly<Apis>;
|
||||||
|
protected _config!: Readonly<ConfigStore>;
|
||||||
protected _logger!: Logger;
|
protected _logger!: Logger;
|
||||||
protected _workspace!: Workspace;
|
protected _workspace!: Workspace;
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@ export class BaseProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init(params: InitialParams) {
|
async init(params: InitialParams) {
|
||||||
|
this._apis = params.apis;
|
||||||
this._config = params.config;
|
this._config = params.config;
|
||||||
this._logger = params.logger;
|
this._logger = params.logger;
|
||||||
this._workspace = params.workspace;
|
this._workspace = params.workspace;
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
import type { Workspace } from '@blocksuite/store';
|
import type { Workspace } from '@blocksuite/store';
|
||||||
|
|
||||||
|
import type { Apis } from '../apis';
|
||||||
import type { getLogger } from '../index';
|
import type { getLogger } from '../index';
|
||||||
import type { ConfigStore } from '../store';
|
import type { ConfigStore } from '../store';
|
||||||
|
|
||||||
export type Logger = ReturnType<typeof getLogger>;
|
export type Logger = ReturnType<typeof getLogger>;
|
||||||
|
|
||||||
export type InitialParams = {
|
export type InitialParams = {
|
||||||
|
apis: Apis;
|
||||||
config: ConfigStore;
|
config: ConfigStore;
|
||||||
debug: boolean;
|
debug: boolean;
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
workspace: Workspace;
|
workspace: Workspace;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type { ConfigStore, Workspace };
|
export type { Apis, ConfigStore, Workspace };
|
||||||
export type { BaseProvider } from './base.js';
|
export type { BaseProvider } from './base.js';
|
||||||
export { AffineProvider } from './affine/index.js';
|
export { AffineProvider } from './affine/index.js';
|
||||||
export { LocalProvider } from './local/index.js';
|
export { LocalProvider } from './local/index.js';
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
export * from './workspace';
|
|
||||||
export * from './user';
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
export const getDataCenter = () => {
|
export const getDataCenter = () => {
|
||||||
return import('../src/datacenter/index.js').then(async dataCenter =>
|
return import('../src/index.js').then(async dataCenter =>
|
||||||
dataCenter.getDataCenter(false)
|
dataCenter.getDataCenter(false)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user