feat: move data center to root

This commit is contained in:
DarkSky 2023-01-02 23:23:29 +08:00 committed by DarkSky
parent 2913da11a0
commit b105eaf9a6
21 changed files with 109 additions and 86 deletions

View File

@ -1,4 +1,4 @@
import { signInWithGoogle } from '@affine/datacenter';
import { getDataCenter } from '@affine/datacenter';
import { styled } from '@/styles';
import { Button } from '@/ui/button';
import { useModal } from '@/providers/global-modal-provider';
@ -9,7 +9,8 @@ export const GoogleLoginButton = () => {
return (
<StyledGoogleButton
onClick={() => {
signInWithGoogle()
getDataCenter()
.then(dc => dc.apis.signInWithGoogle())
.then(() => {
triggerLoginModal();
})

View File

@ -1,19 +1,18 @@
import { createContext, MutableRefObject, useContext } from 'react';
import type { Workspace } from '@affine/datacenter';
import { AccessTokenMessage } from '@affine/datacenter';
import type {
Page as StorePage,
Workspace as StoreWorkspace,
} from '@blocksuite/store';
import type { EditorContainer } from '@blocksuite/editor';
export type LoadWorkspaceHandler = (
workspaceId: string,
user?: AccessTokenMessage | null
workspaceId: string
// user?: AccessTokenMessage | null
) => Promise<StoreWorkspace | null> | null;
export type CreateEditorHandler = (page: StorePage) => EditorContainer | null;
export interface AppStateValue {
user: AccessTokenMessage | null;
// user: AccessTokenMessage | null;
workspacesMeta: Workspace[];
currentWorkspaceId: string;
@ -39,7 +38,7 @@ export interface AppStateContext extends AppStateValue {
}
export const AppState = createContext<AppStateContext>({
user: null,
// user: null,
workspacesMeta: [],
currentWorkspaceId: '',

View 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 };
};

View File

@ -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';
export interface AccessTokenMessage {
interface AccessTokenMessage {
create_at: number;
exp: number;
email: string;
@ -133,3 +137,34 @@ class 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;
}
};

View File

@ -1,5 +1,4 @@
// TODO: temporary reference, move all api into affine provider
import { client } from '../datacenter/provider/affine/request';
import { client } from './request.js';
export interface GetUserByEmailParams {
email: string;

View File

@ -1,6 +1,5 @@
// TODO: temporary reference, move all api into affine provider
import { bareClient, client } from '../datacenter/provider/affine/request';
import { User } from './user';
import { bareClient, client } from './request.js';
import type { User } from './user';
export interface GetWorkspaceDetailParams {
id: string;
@ -165,6 +164,13 @@ export async function getBlob(params: {
export interface LeaveWorkspaceParams {
id: number | string;
}
export async function leaveWorkspace({ id }: LeaveWorkspaceParams) {
await client.delete(`api/workspace/${id}/permission`).json();
}
export async function downloadWorkspace(
workspaceId: string
): Promise<ArrayBuffer> {
return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer();
}

View File

@ -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);
};

View File

@ -3,6 +3,7 @@ import { BlockSchema } from '@blocksuite/blocks/models';
import { Workspace } from '@blocksuite/store';
import { getLogger } from './index.js';
import { getApis, Apis } from './apis/index.js';
import { AffineProvider, BaseProvider } from './provider/index.js';
import { LocalProvider } from './provider/index.js';
import { getKVConfigure } from './store.js';
@ -13,6 +14,7 @@ type GetWorkspaceParams = {
};
export class DataCenter {
private readonly _apis: Apis;
private readonly _providers = new Map<string, typeof BaseProvider>();
private readonly _workspaces = new Map<string, Promise<BaseProvider>>();
private readonly _config;
@ -27,11 +29,16 @@ export class DataCenter {
}
private constructor(debug: boolean) {
this._apis = getApis();
this._config = getKVConfigure('sys');
this._logger = getLogger('dc');
this._logger.enabled = debug;
}
get apis(): Readonly<Apis> {
return this._apis;
}
private addProvider(provider: typeof BaseProvider) {
this._providers.set(provider.id, provider);
}
@ -61,6 +68,7 @@ export class DataCenter {
const provider = new Provider();
await provider.init({
apis: this._apis,
config: getKVConfigure(id),
debug: this._logger.enabled,
logger: this._logger.extend(`${Provider.id}:${id}`),

View File

@ -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;
}

View File

@ -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();
}

View File

@ -1,8 +1,22 @@
export { signInWithGoogle, onAuthStateChanged } from './auth';
export * from './sdks';
import debug from 'debug';
import { DataCenter } from './datacenter.js';
export { getDataCenter } from './datacenter';
const _initializeDataCenter = () => {
let _dataCenterInstance: Promise<DataCenter>;
// TODO: temporary reference, move all api into affine provider
export { token } from './datacenter/provider/affine/token';
export type { AccessTokenMessage } from './datacenter/provider/affine/token';
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;
}

View File

@ -2,11 +2,10 @@ import assert from 'assert';
import { applyUpdate } from 'yjs';
import type { InitialParams } from '../index.js';
import { token, Callback } from '../../apis/index.js';
import { LocalProvider } from '../local/index.js';
import { downloadWorkspace } from './apis.js';
import { WebsocketProvider } from './sync.js';
import { token, Callback } from './token.js';
export class AffineProvider extends LocalProvider {
static id = 'affine';
@ -67,7 +66,7 @@ export class AffineProvider extends LocalProvider {
if (workspace.room && token.isLogin) {
try {
const updates = await downloadWorkspace(workspace.room);
const updates = await this._apis.downloadWorkspace(workspace.room);
if (updates) {
await new Promise(resolve => {
doc.once('update', resolve);

View File

@ -1,11 +1,12 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import type { Workspace } from '@blocksuite/store';
import type { Logger, InitialParams, ConfigStore } from './index';
import type { Apis, Logger, InitialParams, ConfigStore } from './index';
export class BaseProvider {
static id = 'base';
protected _config!: ConfigStore;
protected _apis!: Readonly<Apis>;
protected _config!: Readonly<ConfigStore>;
protected _logger!: Logger;
protected _workspace!: Workspace;
@ -14,6 +15,7 @@ export class BaseProvider {
}
async init(params: InitialParams) {
this._apis = params.apis;
this._config = params.config;
this._logger = params.logger;
this._workspace = params.workspace;

View File

@ -1,18 +1,20 @@
import type { Workspace } from '@blocksuite/store';
import type { Apis } from '../apis';
import type { getLogger } from '../index';
import type { ConfigStore } from '../store';
export type Logger = ReturnType<typeof getLogger>;
export type InitialParams = {
apis: Apis;
config: ConfigStore;
debug: boolean;
logger: Logger;
workspace: Workspace;
};
export type { ConfigStore, Workspace };
export type { Apis, ConfigStore, Workspace };
export type { BaseProvider } from './base.js';
export { AffineProvider } from './affine/index.js';
export { LocalProvider } from './local/index.js';

View File

@ -1,2 +0,0 @@
export * from './workspace';
export * from './user';

View File

@ -1,5 +1,5 @@
export const getDataCenter = () => {
return import('../src/datacenter/index.js').then(async dataCenter =>
return import('../src/index.js').then(async dataCenter =>
dataCenter.getDataCenter(false)
);
};