merge branch develop into branch feat/doublelink220820

This commit is contained in:
xiaodong zuo
2022-09-06 10:01:09 +08:00
20 changed files with 284 additions and 260 deletions
@@ -39,7 +39,7 @@ async function _getCurrentToken() {
const _enabled = {
demo: [],
AFFiNE: ['sqlite'],
AFFiNE: ['idb'],
} as any;
async function _getBlockDatabase(
@@ -36,7 +36,7 @@ export class UserConfig extends ServiceBaseClass {
}
const db = await this.database.getDatabase(workspace);
const newPage = await db.get('page');
const newPage = await db.getNamedBlock('start-page');
await this.get_dependency(PageTree).addPage(workspace, newPage.id);
await this.addRecentPage(workspace, userId, newPage.id);
+2 -2
View File
@@ -357,7 +357,7 @@ export class BlockClient<
* @param name block name
* @returns block instance
*/
private async get_named_block(
public async getNamedBlock(
name: string,
options?: { workspace?: boolean }
): Promise<BaseBlock<B, C>> {
@@ -376,7 +376,7 @@ export class BlockClient<
*/
public async getWorkspace() {
if (!this._root.node) {
this._root.node = await this.get_named_block(this._workspace, {
this._root.node = await this.getNamedBlock(this._workspace, {
workspace: true,
});
}
+63 -46
View File
@@ -56,6 +56,7 @@ type YjsProviders = {
connListener: { listeners?: ConnectivityListener };
userId: string;
remoteToken: string | undefined; // remote storage token
providers: unknown[];
};
const _yjsDatabaseInstance = new Map<string, YjsProviders>();
@@ -107,19 +108,25 @@ async function _initYjsDatabase(
);
const connListener: { listeners?: ConnectivityListener } = {};
let providers: unknown[] = [];
if (options.provider) {
const emitState = (c: Connectivity) =>
connListener.listeners?.(workspace, c);
await Promise.all(
Object.entries(options.provider).flatMap(([, p]) => [
p({ awareness, doc, token, workspace, emitState }),
providers = await Promise.all(
Object.entries(options.provider).flatMap(([name, p]) => [
p({ awareness, doc, token, workspace, emitState }).then(p => {
console.log(p);
return {
[name]: p,
};
}),
p({
awareness,
doc: binaries,
token,
workspace: `${workspace}_binaries`,
emitState,
}),
}).then(p => ({ [`${name}_binaries`]: p })),
])
);
}
@@ -128,7 +135,7 @@ async function _initYjsDatabase(
binaries,
doc,
gatekeeper,
providers,
connListener,
userId,
remoteToken: token,
@@ -324,53 +331,63 @@ export class YjsAdapter implements AsyncDatabaseAdapter<YjsContentOperation> {
const binary = encodeStateAsUpdate(this._doc);
saveAs(
new Blob([binary]),
`affine_workspace_${new Date().toDateString()}.apk`
`affine_workspace_${new Date().toDateString()}.affine`
);
},
load: async () => {
const handles = await window.showOpenFilePicker({
types: [
{
description: 'AFFiNE Package',
accept: {
// eslint-disable-next-line @typescript-eslint/naming-convention
'application/affine': ['.apk'],
try {
const handles = await window.showOpenFilePicker({
types: [
{
description: 'AFFiNE Package',
accept: {
// eslint-disable-next-line @typescript-eslint/naming-convention
'application/affine': ['.affine'],
},
},
},
],
});
const [file] = (await fromEvent(handles)) as File[];
const binary = await file?.arrayBuffer();
// await this._provider.idb.clearData();
const doc = new Doc({ autoLoad: true, shouldLoad: true });
let updated = 0;
let isUpdated = false;
doc.on('update', () => {
isUpdated = true;
updated += 1;
});
setInterval(() => {
if (updated > 0) {
updated -= 1;
}
}, 500);
const update_check = new Promise<void>(resolve => {
const check = async () => {
while (!isUpdated || updated > 0) {
await sleep();
],
});
const [file] = (await fromEvent(handles)) as File[];
const binary = await file?.arrayBuffer();
console.log(this._provider.providers);
let { indexeddb } = (
this._provider.providers as any[]
).find(p => p.indexeddb);
await indexeddb?.idb?.clearData();
const doc = new Doc({ autoLoad: true, shouldLoad: true });
let updated = 0;
let isUpdated = false;
doc.on('update', () => {
isUpdated = true;
updated += 1;
});
setInterval(() => {
if (updated > 0) {
updated -= 1;
}
resolve();
};
check();
});
// await new IndexedDBProvider(this._provider.idb.name, doc)
// .whenSynced;
if (binary) {
applyUpdate(doc, new Uint8Array(binary));
await update_check;
}, 500);
const update_check = new Promise<void>(resolve => {
const check = async () => {
while (!isUpdated || updated > 0) {
await sleep();
}
resolve();
};
check();
});
await new indexeddb.ctor(indexeddb.idb.name, doc)
.whenSynced;
if (binary) {
applyUpdate(doc, new Uint8Array(binary));
await update_check;
}
return true;
} catch (err) {
console.log(err);
return false;
}
console.log('load success');
},
parse: () => this._doc.toJSON(),
// eslint-disable-next-line @typescript-eslint/naming-convention
+8 -3
View File
@@ -18,7 +18,9 @@ type YjsDefaultInstances = {
emitState: (connectivity: Connectivity) => void;
};
export type YjsProvider = (instances: YjsDefaultInstances) => Promise<void>;
export type YjsProvider = (
instances: YjsDefaultInstances
) => Promise<unknown | undefined>;
type ProviderType = 'idb' | 'sqlite' | 'ws';
@@ -38,9 +40,12 @@ export const getYjsProviders = (
return {
indexeddb: async (instances: YjsDefaultInstances) => {
if (options.enabled.includes('idb')) {
await new IndexedDBProvider(instances.workspace, instances.doc)
.whenSynced;
return new IndexedDBProvider(
instances.workspace,
instances.doc
).whenSynced.then(idb => ({ idb, ctor: IndexedDBProvider }));
}
return undefined;
},
sqlite: async (instances: YjsDefaultInstances) => {
if (options.enabled.includes('sqlite')) {
+9 -33
View File
@@ -71,44 +71,20 @@ const _useUserAndSpacesForFreeLogin = () => {
useEffect(() => {
if (loading) {
if (location.pathname.startsWith('/local')) {
navigate('/local');
} else {
navigate('/demo');
}
navigate(`/${BRAND_ID}`);
setLoading(false);
}
}, []);
useEffect(() => {
if (localTrigger) {
setUser({
photo: '',
id: BRAND_ID,
username: BRAND_ID,
nickname: BRAND_ID,
email: '',
});
} else {
if (location.pathname.startsWith('/local')) {
setUser({
photo: '',
id: 'local',
username: 'local',
nickname: 'local',
email: '',
});
} else {
setUser({
photo: '',
id: 'demo',
username: 'demo',
nickname: 'demo',
email: '',
});
}
}
}, [localTrigger, location, setLoading, setUser]);
setUser({
photo: '',
id: BRAND_ID,
username: BRAND_ID,
nickname: BRAND_ID,
email: '',
});
}, [setUser]);
const currentSpaceId: string | undefined = useMemo(() => user?.id, [user]);