feat(core): use zip snapshot for onboarding page (#6495)
This commit is contained in:
17 files changed
+108
-2009
No files matched your search
@@ -1,17 +1,4 @@
|
|||||||
import type { WorkspaceFlavour } from '@affine/env/workspace';
|
import type { Doc } from '@blocksuite/store';
|
||||||
import type {
|
|
||||||
CollectionInfoSnapshot,
|
|
||||||
Doc,
|
|
||||||
DocSnapshot,
|
|
||||||
JobMiddleware,
|
|
||||||
} from '@blocksuite/store';
|
|
||||||
import { Job } from '@blocksuite/store';
|
|
||||||
import { Map as YMap } from 'yjs';
|
|
||||||
|
|
||||||
import { getLatestVersions } from '../blocksuite/migration/blocksuite';
|
|
||||||
import { PageRecordList } from '../page';
|
|
||||||
import type { WorkspaceManager } from '../workspace';
|
|
||||||
import { replaceIdMiddleware } from './middleware';
|
|
||||||
|
|
||||||
export function initEmptyPage(page: Doc, title?: string) {
|
export function initEmptyPage(page: Doc, title?: string) {
|
||||||
page.load(() => {
|
page.load(() => {
|
||||||
@@ -38,108 +25,3 @@ export function initEmptyPage(page: Doc, title?: string) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* FIXME: Use exported json data to instead of building data.
|
|
||||||
*/
|
|
||||||
export async function buildShowcaseWorkspace(
|
|
||||||
workspaceManager: WorkspaceManager,
|
|
||||||
flavour: WorkspaceFlavour,
|
|
||||||
workspaceName: string
|
|
||||||
) {
|
|
||||||
const meta = await workspaceManager.createWorkspace(
|
|
||||||
flavour,
|
|
||||||
async (docCollection, blobStorage) => {
|
|
||||||
docCollection.meta.setName(workspaceName);
|
|
||||||
const { onboarding } = await import('@affine/templates');
|
|
||||||
|
|
||||||
const info = onboarding['info.json'] as CollectionInfoSnapshot;
|
|
||||||
const blob = onboarding['blob.json'] as { [key: string]: string };
|
|
||||||
|
|
||||||
const migrationMiddleware: JobMiddleware = ({ slots, collection }) => {
|
|
||||||
slots.afterImport.on(payload => {
|
|
||||||
if (payload.type === 'page') {
|
|
||||||
collection.schema.upgradeDoc(
|
|
||||||
info?.pageVersion ?? 0,
|
|
||||||
{},
|
|
||||||
payload.page.spaceDoc
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const job = new Job({
|
|
||||||
collection: docCollection,
|
|
||||||
middlewares: [replaceIdMiddleware, migrationMiddleware],
|
|
||||||
});
|
|
||||||
|
|
||||||
job.snapshotToCollectionInfo(info);
|
|
||||||
|
|
||||||
// for now all onboarding assets are considered served via CDN
|
|
||||||
// hack assets so that every blob exists
|
|
||||||
// @ts-expect-error - rethinking API
|
|
||||||
job._assetsManager.writeToBlob = async () => {};
|
|
||||||
|
|
||||||
const docSnapshots: DocSnapshot[] = Object.entries(onboarding)
|
|
||||||
.filter(([key]) => {
|
|
||||||
return key.endsWith('snapshot.json');
|
|
||||||
})
|
|
||||||
.map(([_, value]) => value as unknown as DocSnapshot);
|
|
||||||
|
|
||||||
await Promise.all(
|
|
||||||
docSnapshots.map(snapshot => {
|
|
||||||
return job.snapshotToDoc(snapshot);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const newVersions = getLatestVersions(docCollection.schema);
|
|
||||||
docCollection.doc
|
|
||||||
.getMap('meta')
|
|
||||||
.set('blockVersions', new YMap(Object.entries(newVersions)));
|
|
||||||
|
|
||||||
for (const [key, base64] of Object.entries(blob)) {
|
|
||||||
await blobStorage.set(key, new Blob([base64ToUint8Array(base64)]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const { workspace, release } = workspaceManager.open(meta);
|
|
||||||
|
|
||||||
await workspace.engine.waitForRootDocReady();
|
|
||||||
|
|
||||||
const pageRecordList = workspace.services.get(PageRecordList);
|
|
||||||
|
|
||||||
// todo: find better way to do the following
|
|
||||||
// perhaps put them into middleware?
|
|
||||||
{
|
|
||||||
// the "Write, Draw, Plan all at Once." page should be set to edgeless mode
|
|
||||||
const edgelessPage1 = pageRecordList.records$.value.find(
|
|
||||||
p => p.title$.value === 'Write, Draw, Plan all at Once.'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (edgelessPage1) {
|
|
||||||
edgelessPage1.setMode('edgeless');
|
|
||||||
}
|
|
||||||
|
|
||||||
// should jump to "Write, Draw, Plan all at Once." by default
|
|
||||||
const defaultPage = pageRecordList.records$.value.find(p =>
|
|
||||||
p.title$.value.startsWith('Write, Draw, Plan all at Once.')
|
|
||||||
);
|
|
||||||
|
|
||||||
if (defaultPage) {
|
|
||||||
defaultPage.setMeta({
|
|
||||||
jumpOnce: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
release();
|
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
function base64ToUint8Array(base64: string) {
|
|
||||||
const binaryString = atob(base64);
|
|
||||||
const binaryArray = binaryString.split('').map(function (char) {
|
|
||||||
return char.charCodeAt(0);
|
|
||||||
});
|
|
||||||
return new Uint8Array(binaryArray);
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
||||||
/* eslint-disable @typescript-eslint/no-restricted-imports */
|
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
||||||
// @ts-nocheck
|
|
||||||
// TODO: remove this file after blocksuite exposed it
|
|
||||||
import type {
|
|
||||||
DatabaseBlockModel,
|
|
||||||
ListBlockModel,
|
|
||||||
ParagraphBlockModel,
|
|
||||||
} from '@blocksuite/blocks/dist/models.js';
|
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
|
||||||
import type { DeltaOperation, JobMiddleware } from '@blocksuite/store';
|
|
||||||
|
|
||||||
export const replaceIdMiddleware: JobMiddleware = ({ slots, collection }) => {
|
|
||||||
const idMap = new Map<string, string>();
|
|
||||||
slots.afterImport.on(payload => {
|
|
||||||
if (
|
|
||||||
payload.type === 'block' &&
|
|
||||||
payload.snapshot.flavour === 'affine:database'
|
|
||||||
) {
|
|
||||||
const model = payload.model as DatabaseBlockModel;
|
|
||||||
Object.keys(model.cells).forEach(cellId => {
|
|
||||||
if (idMap.has(cellId)) {
|
|
||||||
model.cells[idMap.get(cellId)!] = model.cells[cellId];
|
|
||||||
delete model.cells[cellId];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace LinkedPage pageId with new id in paragraph blocks
|
|
||||||
if (
|
|
||||||
payload.type === 'block' &&
|
|
||||||
['affine:paragraph', 'affine:list'].includes(payload.snapshot.flavour)
|
|
||||||
) {
|
|
||||||
const model = payload.model as ParagraphBlockModel | ListBlockModel;
|
|
||||||
let prev = 0;
|
|
||||||
const delta: DeltaOperation[] = [];
|
|
||||||
for (const d of model.text.toDelta()) {
|
|
||||||
if (d.attributes?.reference?.pageId) {
|
|
||||||
if (prev > 0) {
|
|
||||||
delta.push({ retain: prev });
|
|
||||||
}
|
|
||||||
delta.push({
|
|
||||||
retain: d.insert.length,
|
|
||||||
attributes: {
|
|
||||||
reference: {
|
|
||||||
...d.attributes.reference,
|
|
||||||
pageId: idMap.get(d.attributes.reference.pageId)!,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
prev = 0;
|
|
||||||
} else {
|
|
||||||
prev += d.insert.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (delta.length > 0) {
|
|
||||||
model.text.applyDelta(delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
slots.beforeImport.on(payload => {
|
|
||||||
if (payload.type === 'page') {
|
|
||||||
const newId = collection.idGenerator('page');
|
|
||||||
idMap.set(payload.snapshot.meta.id, newId);
|
|
||||||
payload.snapshot.meta.id = newId;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (payload.type === 'block') {
|
|
||||||
const { snapshot } = payload;
|
|
||||||
if (snapshot.flavour === 'affine:page') {
|
|
||||||
const index = snapshot.children.findIndex(
|
|
||||||
c => c.flavour === 'affine:surface'
|
|
||||||
);
|
|
||||||
if (index !== -1) {
|
|
||||||
const [surface] = snapshot.children.splice(index, 1);
|
|
||||||
snapshot.children.push(surface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const original = snapshot.id;
|
|
||||||
let newId: string;
|
|
||||||
if (idMap.has(original)) {
|
|
||||||
newId = idMap.get(original)!;
|
|
||||||
} else {
|
|
||||||
newId = collection.idGenerator('block');
|
|
||||||
idMap.set(original, newId);
|
|
||||||
}
|
|
||||||
snapshot.id = newId;
|
|
||||||
|
|
||||||
if (snapshot.flavour === 'affine:surface') {
|
|
||||||
// Generate new IDs for images and frames in advance.
|
|
||||||
snapshot.children.forEach(child => {
|
|
||||||
const original = child.id;
|
|
||||||
if (idMap.has(original)) {
|
|
||||||
newId = idMap.get(original)!;
|
|
||||||
} else {
|
|
||||||
newId = collection.idGenerator('block');
|
|
||||||
idMap.set(original, newId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.entries(
|
|
||||||
snapshot.props.elements as Record<string, Record<string, unknown>>
|
|
||||||
).forEach(([_, value]) => {
|
|
||||||
switch (value.type) {
|
|
||||||
case 'connector': {
|
|
||||||
let connection = value.source as Record<string, string>;
|
|
||||||
if (idMap.has(connection.id)) {
|
|
||||||
const newId = idMap.get(connection.id);
|
|
||||||
assertExists(newId, 'reference id must exist');
|
|
||||||
connection.id = newId;
|
|
||||||
}
|
|
||||||
connection = value.target as Record<string, string>;
|
|
||||||
if (idMap.has(connection.id)) {
|
|
||||||
const newId = idMap.get(connection.id);
|
|
||||||
assertExists(newId, 'reference id must exist');
|
|
||||||
connection.id = newId;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'group': {
|
|
||||||
const json = value.children.json as Record<string, unknown>;
|
|
||||||
Object.entries(json).forEach(([key, value]) => {
|
|
||||||
if (idMap.has(key)) {
|
|
||||||
delete json[key];
|
|
||||||
const newKey = idMap.get(key);
|
|
||||||
assertExists(newKey, 'reference id must exist');
|
|
||||||
json[newKey] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -57,6 +57,13 @@ export class TestingLocalWorkspaceListProvider
|
|||||||
id: id,
|
id: id,
|
||||||
idGenerator: () => nanoid(),
|
idGenerator: () => nanoid(),
|
||||||
schema: globalBlockSuiteSchema,
|
schema: globalBlockSuiteSchema,
|
||||||
|
blobStorages: [
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
crud: blobStorage,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
// apply initial state
|
// apply initial state
|
||||||
|
|||||||
@@ -1,8 +1,61 @@
|
|||||||
import { DebugLogger } from '@affine/debug';
|
import { DebugLogger } from '@affine/debug';
|
||||||
import { DEFAULT_WORKSPACE_NAME } from '@affine/env/constant';
|
import { DEFAULT_WORKSPACE_NAME } from '@affine/env/constant';
|
||||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||||
import type { WorkspaceManager } from '@toeverything/infra';
|
import onboardingUrl from '@affine/templates/onboarding.zip';
|
||||||
import { buildShowcaseWorkspace, initEmptyPage } from '@toeverything/infra';
|
import { ZipTransformer } from '@blocksuite/blocks';
|
||||||
|
import {
|
||||||
|
initEmptyPage,
|
||||||
|
PageRecordList,
|
||||||
|
type WorkspaceManager,
|
||||||
|
} from '@toeverything/infra';
|
||||||
|
|
||||||
|
export async function buildShowcaseWorkspace(
|
||||||
|
workspaceManager: WorkspaceManager,
|
||||||
|
flavour: WorkspaceFlavour,
|
||||||
|
workspaceName: string
|
||||||
|
) {
|
||||||
|
const meta = await workspaceManager.createWorkspace(
|
||||||
|
flavour,
|
||||||
|
async docCollection => {
|
||||||
|
docCollection.meta.setName(workspaceName);
|
||||||
|
const blob = await (await fetch(onboardingUrl)).blob();
|
||||||
|
|
||||||
|
await ZipTransformer.importDocs(docCollection, blob);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const { workspace, release } = workspaceManager.open(meta);
|
||||||
|
|
||||||
|
await workspace.engine.waitForRootDocReady();
|
||||||
|
|
||||||
|
const pageRecordList = workspace.services.get(PageRecordList);
|
||||||
|
|
||||||
|
// todo: find better way to do the following
|
||||||
|
// perhaps put them into middleware?
|
||||||
|
{
|
||||||
|
// the "Write, Draw, Plan all at Once." page should be set to edgeless mode
|
||||||
|
const edgelessPage1 = pageRecordList.records$.value.find(
|
||||||
|
p => p.title$.value === 'Write, Draw, Plan all at Once.'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (edgelessPage1) {
|
||||||
|
edgelessPage1.setMode('edgeless');
|
||||||
|
}
|
||||||
|
|
||||||
|
// should jump to "Write, Draw, Plan all at Once." by default
|
||||||
|
const defaultPage = pageRecordList.records$.value.find(p =>
|
||||||
|
p.title$.value.startsWith('Write, Draw, Plan all at Once.')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (defaultPage) {
|
||||||
|
defaultPage.setMeta({
|
||||||
|
jumpOnce: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
release();
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
const logger = new DebugLogger('createFirstAppData');
|
const logger = new DebugLogger('createFirstAppData');
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { WorkspaceFlavour } from '@affine/env/workspace';
|
|||||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||||
import { _addLocalWorkspace } from '@affine/workspace-impl';
|
import { _addLocalWorkspace } from '@affine/workspace-impl';
|
||||||
import {
|
import {
|
||||||
buildShowcaseWorkspace,
|
|
||||||
initEmptyPage,
|
initEmptyPage,
|
||||||
useService,
|
useService,
|
||||||
WorkspaceManager,
|
WorkspaceManager,
|
||||||
@@ -19,6 +18,7 @@ import { useSetAtom } from 'jotai';
|
|||||||
import type { KeyboardEvent } from 'react';
|
import type { KeyboardEvent } from 'react';
|
||||||
import { useCallback, useLayoutEffect, useState } from 'react';
|
import { useCallback, useLayoutEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { buildShowcaseWorkspace } from '../../../bootstrap/first-app-data';
|
||||||
import { mixpanel } from '../../../utils';
|
import { mixpanel } from '../../../utils';
|
||||||
import { CloudSvg } from '../share-page-modal/cloud-svg';
|
import { CloudSvg } from '../share-page-modal/cloud-svg';
|
||||||
import * as styles from './index.css';
|
import * as styles from './index.css';
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useWorkspace } from '@affine/core/hooks/use-workspace';
|
import { useWorkspace } from '@affine/core/hooks/use-workspace';
|
||||||
|
import { ZipTransformer } from '@blocksuite/blocks';
|
||||||
import type { Workspace } from '@toeverything/infra';
|
import type { Workspace } from '@toeverything/infra';
|
||||||
import {
|
import {
|
||||||
ServiceProviderContext,
|
ServiceProviderContext,
|
||||||
@@ -28,6 +29,8 @@ declare global {
|
|||||||
*/
|
*/
|
||||||
// eslint-disable-next-line no-var
|
// eslint-disable-next-line no-var
|
||||||
var currentWorkspace: Workspace | undefined;
|
var currentWorkspace: Workspace | undefined;
|
||||||
|
// eslint-disable-next-line no-var
|
||||||
|
var exportWorkspaceSnapshot: () => Promise<void>;
|
||||||
interface WindowEventMap {
|
interface WindowEventMap {
|
||||||
'affine:workspace:change': CustomEvent<{ id: string }>;
|
'affine:workspace:change': CustomEvent<{ id: string }>;
|
||||||
}
|
}
|
||||||
@@ -60,6 +63,19 @@ export const Component = (): ReactElement => {
|
|||||||
|
|
||||||
// for debug purpose
|
// for debug purpose
|
||||||
window.currentWorkspace = workspace;
|
window.currentWorkspace = workspace;
|
||||||
|
window.exportWorkspaceSnapshot = async () => {
|
||||||
|
const zip = await ZipTransformer.exportDocs(
|
||||||
|
workspace.docCollection,
|
||||||
|
Array.from(workspace.docCollection.docs.values())
|
||||||
|
);
|
||||||
|
const url = URL.createObjectURL(zip);
|
||||||
|
// download url
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = `${workspace.docCollection.meta.name}.zip`;
|
||||||
|
a.click();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
};
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('affine:workspace:change', {
|
new CustomEvent('affine:workspace:change', {
|
||||||
detail: {
|
detail: {
|
||||||
|
|||||||
+5
@@ -14,6 +14,11 @@ declare module '*.assets.svg' {
|
|||||||
export default url;
|
export default url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module '*.zip' {
|
||||||
|
const url: string;
|
||||||
|
export default url;
|
||||||
|
}
|
||||||
|
|
||||||
declare module '*.png' {
|
declare module '*.png' {
|
||||||
const url: string;
|
const url: string;
|
||||||
export default url;
|
export default url;
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
import fs from 'node:fs';
|
|
||||||
import path, { join } from 'node:path';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
|
|
||||||
import * as glob from 'glob';
|
|
||||||
|
|
||||||
// purpose: bundle all json files into one json file in onboarding folder
|
|
||||||
const __dirname = join(fileURLToPath(import.meta.url), '..');
|
|
||||||
|
|
||||||
const jsonFiles = glob.sync('./*.json', {
|
|
||||||
cwd: path.join(__dirname, 'onboarding'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const imports = jsonFiles
|
|
||||||
.map(
|
|
||||||
(fileName, index) => `import json_${index} from './onboarding/${fileName}';`
|
|
||||||
)
|
|
||||||
.join('\n');
|
|
||||||
|
|
||||||
const exports = `export const onboarding = {
|
|
||||||
${jsonFiles
|
|
||||||
.map((fileName, index) => {
|
|
||||||
return ` '${fileName}': json_${index}`;
|
|
||||||
})
|
|
||||||
.join(',\n')}
|
|
||||||
}`;
|
|
||||||
|
|
||||||
const template = `/* eslint-disable simple-import-sort/imports */
|
|
||||||
// Auto generated, do not edit manually
|
|
||||||
${imports}\n\n${exports}`;
|
|
||||||
|
|
||||||
fs.writeFileSync(path.join(__dirname, 'templates.gen.ts'), template);
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"ZRKpsBoC88qEMmeiXKXqywfA1rLvWoLa5rpEh9x9Oj0=": "iVBORw0KGgoAAAANSUhEUgAAA14AAAVsCAYAAAAoukxuAAAMPmlDQ1BJQ0MgUHJvZmlsZQAASImVVwdYU8kWnluSkJAQIICAlNCbICIlgJQQWugdwUZIAoQSYyCo2NFFBdcuFrChqyIKVkDsiJ1FsffFgoKyLhbsypsU0HVf+d75vrn3v/+c+c+Zc+eWAYB+gieR5KKaAOSJC6RxIQHM0SmpTFIXQAAdUAEKDHj8fAk7JiYCQBs4/93e3YDe0K46yrX+2f9fTUsgzOcDgMRAnC7I5+dBfAAAvJIvkRYAQJTzFpMLJHIMG9CRwgQhXiDHmUpcKcfpSrxH4ZMQx4G4BQA1Ko8nzQRA4zLkmYX8TKih0Quxs1ggEgNAZ0Lsm5c3UQBxGsS20EcCsVyflf6DTubfNNMHNXm8zEGsnIvC1AJF+ZJc3tT/sxz/2/JyZQMxrGGjZklD4+RzhnW7lTMxXI6pEPeI06OiIdaG+INIoPCHGKVkyUITlf6oET+fA2sG9CB2FvACwyE2gjhYnBsVoeLTM0TBXIjhCkGniAq4CRDrQ7xAmB8Ur/LZJJ0Yp4qF1mdIOWwVf44nVcSVx3ogy0lkq/RfZwm5Kn1MoygrIRliCsSWhaKkKIg1IHbKz4kPV/mMKsriRA34SGVx8vwtIY4TikMClPpYYYY0OE7lX5qXPzBfbFOWiBulwvsKshJClfXBWvg8Rf5wLthloZidOKAjzB8dMTAXgTAwSDl3rEsoToxX6XyQFATEKcfiFElujMofNxfmhsh5c4hd8wvjVWPxpAK4IJX6eIakICZBmSdelM0Li1Hmgy8FEYADAgETyGBLBxNBNhC19TT0wCtlTzDgASnIBELgqGIGRiQresTwGA+KwJ8QCUH+4LgARa8QFEL+6yCrPDqCDEVvoWJEDngKcR4IB7nwWqYYJR6MlgSeQEb0j+g82Pgw31zY5P3/nh9gvzNsyESoGNlARCZ9wJMYRAwkhhKDiXa4Ie6Le+MR8OgPmwvOwj0H5vHdn/CU0E54RLhO6CDcniAqlv6UZSTogPrBqlqk/1gL3BpquuEBuA9Uh8q4Hm4IHHFXGIeN+8HIbpDlqPKWV4X5k/bfZvDD3VD5kZ3JKHkI2Z9s+/NIDXsNt0EVea1/rI8y1/TBenMGe36Oz/mh+gJ4Dv/ZE1uA7cfOYiex89gRrAEwseNYI9aKHZXjwdX1RLG6BqLFKfLJgTqif8QbuLPySuY71zh3O39R9hUIp8jf0YAzUTJVKsrMKmCy4RdByOSK+U7DmC7OLq4AyL8vytfXm1jFdwPRa/3Ozf0DAJ/j/f39h79zYccB2OsBH/9D3zlbFvx0qANw7hBfJi1Ucrj8QIBvCTp80gyACbAAtnA+LsAdeAN/EATCQDRIAClgPMw+C65zKZgMpoM5oASUgaVgFVgHNoItYAfYDfaBBnAEnARnwEVwGVwHd+Hq6QQvQC94Bz4jCEJCaAgDMUBMESvEAXFBWIgvEoREIHFICpKGZCJiRIZMR+YiZchyZB2yGalG9iKHkJPIeaQduY08RLqR18gnFEOpqA5qjFqjw1EWykbD0QR0HJqJTkKL0HnoYnQNWoXuQuvRk+hF9Dragb5A+zCAqWN6mBnmiLEwDhaNpWIZmBSbiZVi5VgVVos1wft8FevAerCPOBFn4EzcEa7gUDwR5+OT8Jn4InwdvgOvx1vwq/hDvBf/RqARjAgOBC8ClzCakEmYTCghlBO2EQ4STsNnqZPwjkgk6hFtiB7wWUwhZhOnERcR1xPriCeI7cTHxD4SiWRAciD5kKJJPFIBqYS0lrSLdJx0hdRJ+qCmrmaq5qIWrJaqJlYrVitX26l2TO2K2jO1z2RNshXZixxNFpCnkpeQt5KbyJfIneTPFC2KDcWHkkDJpsyhrKHUUk5T7lHeqKurm6t7qseqi9Rnq69R36N+Tv2h+keqNtWeyqGOpcqoi6nbqSeot6lvaDSaNc2flkoroC2mVdNO0R7QPmgwNJw0uBoCjVkaFRr1Glc0XtLJdCs6mz6eXkQvp++nX6L3aJI1rTU5mjzNmZoVmoc0b2r2aTG0RmhFa+VpLdLaqXVeq0ubpG2tHaQt0J6nvUX7lPZjBsawYHAYfMZcxlbGaUanDlHHRoerk61TprNbp02nV1db11U3SXeKboXuUd0OPUzPWo+rl6u3RG+f3g29T0OMh7CHCIcsHFI75MqQ9/pD9f31hfql+nX61/U/GTANggxyDJYZNBjcN8QN7Q1jDScbbjA8bdgzVGeo91D+0NKh+4beMUKN7I3ijKYZbTFqNeozNjEOMZYYrzU+Zdxjomfib5JtstLkmEm3KcPU11RkutL0uOlzpi6TzcxlrmG2MHvNjMxCzWRmm83azD6b25gnmheb15nft6BYsCwyLFZaNFv0WppaRlpOt6yxvGNFtmJZZVmttjpr9d7axjrZer51g3WXjb4N16bIpsbmni3N1s92km2V7TU7oh3LLsduvd1le9TezT7LvsL+kgPq4O4gcljv0D6MMMxzmHhY1bCbjlRHtmOhY43jQyc9pwinYqcGp5fDLYenDl82/Ozwb85uzrnOW53vjtAeETaieETTiNcu9i58lwqXayNpI4NHzhrZOPKVq4Or0HWD6y03hluk23y3Zrev7h7uUvda924PS480j0qPmywdVgxrEeucJ8EzwHOW5xHPj17uXgVe+7z+8nb0zvHe6d01ymaUcNTWUY99zH14Ppt9OnyZvmm+m3w7/Mz8eH5Vfo/8LfwF/tv8n7Ht2NnsXeyXAc4B0oCDAe85XpwZnBOBWGBIYGlgW5B2UGLQuqAHwebBmcE1wb0hbiHTQk6EEkLDQ5eF3uQac/ncam5vmEfYjLCWcGp4fPi68EcR9hHSiKZINDIsckXkvSirKHFUQzSI5kaviL4fYxMzKeZwLDE2JrYi9mnciLjpcWfjGfET4nfGv0sISFiScDfRNlGW2JxETxqbVJ30PjkweXlyx+jho2eMvphimCJKaUwlpSalbkvtGxM0ZtWYzrFuY0vG3hhnM27KuPPjDcfnjj86gT6BN2F/GiEtOW1n2hdeNK+K15fOTa9M7+Vz+Kv5LwT+gpWCbqGPcLnwWYZPxvKMrkyfzBWZ3Vl+WeVZPSKOaJ3oVXZo9sbs9znROdtz+nOTc+vy1PLS8g6JtcU54paJJhOnTGyXOEhKJB2TvCatmtQrDZduy0fyx+U3FujAH/lWma3sF9nDQt/CisIPk5Mm75+iNUU8pXWq/dSFU58VBRf9Ng2fxp/WPN1s+pzpD2ewZ2yeicxMn9k8y2LWvFmds0Nm75hDmZMz5/di5+LlxW/nJs9tmmc8b/a8x7+E/FJTolEiLbk533v+xgX4AtGCtoUjF65d+K1UUHqhzLmsvOzLIv6iC7+O+HXNr/2LMxa3LXFfsmEpcal46Y1lfst2LNdaXrT88YrIFfUrmStLV75dNWHV+XLX8o2rKatlqzvWRKxpXGu5dunaL+uy1l2vCKioqzSqXFj5fr1g/ZUN/htqNxpvLNv4aZNo063NIZvrq6yryrcQtxRuebo1aevZ31i/VW8z3Fa27et28faOHXE7Wqo9qqt3Gu1cUoPWyGq6d43ddXl34O7GWsfazXV6dWV7wB7Znud70/be2Be+r3k/a3/tAasDlQcZB0vrkfqp9b0NWQ0djSmN7YfCDjU3eTcdPOx0ePsRsyMVR3WPLjlGOTbvWP/xouN9JyQnek5mnnzcPKH57qnRp661xLa0nQ4/fe5M8JlTZ9lnj5/zOXfkvNf5QxdYFxouul+sb3VrPfi72+8H29zb6i95XGq87Hm5qX1U+7ErfldOXg28euYa99rF61HX228k3rh1c+zNjluCW123c2+/ulN45/Pd2fcI90rva94vf2D0oOoPuz/qOtw7jj4MfNj6KP7R3cf8xy+e5D/50jnvKe1p+TPTZ9VdLl1HuoO7Lz8f87zzheTF556SP7X+rHxp+/LAX/5/tfaO7u18JX3V/3rRG4M329+6vm3ui+l78C7v3ef3pR8MPuz4yPp49lPyp2efJ38hfVnz1e5r07fwb/f68/r7JTwpT/ErgMGGZmQA8Ho7ALQUABhwf0YZo9z/KQxR7lkVCPwnrNwjKswdgFr4/x7bA/9ubgKwZyvcfkF9+lgAYmgAJHgCdOTIwTawV1PsK+VGhPuATTFf0/PSwb8x5Z7zh7x/PgO5qiv4+fwv6CJ8Q+JJh9YAAAA4ZVhJZk1NACoAAAAIAAGHaQAEAAAAAQAAABoAAAAAAAKgAgAEAAAAAQAAA16gAwAEAAAAAQAABWwAAAAAjZaPtQAAQABJREFUeAHs3Wt2HMeZ4P2ILAC8igQpy7ba8hh622M3reMx3e+X+SSXV2B5BaJXIHkFtFcgewWSVyB5BSr3zJzTM+d0i7YPxXGP+yU0llsXmiR4A0EAlfFGJFAgCihU5SUyrv88RwJQyMyI+EUCxFMR8YQUHAgggAACCLQUULeHq2JLrJrLd4VYk0p/Lve+LsdiVe5/LoX61kERUqxNPj98/uQ181Gp5+ccfr3O57rM9aPnKXHkNfX8ayXkJ+Z8XeZGMRAb1ef75yv99fJYbMgro3XzOgcCCCCAAAJtBWTbC7kOAQQQQCA9gUkgVQVROpCaBE9V4LQXRK3qfzjWTMu7BEexylVBnQ7QlKwCtA1hPteBWxW0FWLdvF4Fa8tiXb46qoK4WNtKvRFAAAEE7AoQeNn15G4IIIBAsALq1nBtElCpUqwVUlxUQplRqjUzSpVjINV3Z5lAbX+0bUMKuT4uxSfFfoC2pEfVGEnruwe4PwIIIBCOAIFXOH1BTRBAAIFOAiawGitx1QRROpj6gVLKjE5VXxNUdaLt9eLDwZlS8vfSBGY6KCMw65WdmyOAAALOBQi8nJNTIAIIINBeYBJclXrEalCIb1UjVjLine truncated
|
|
||||||
"BFZk3c2ERp-sliRvA7MQ_p3NdkdCLt2Ze0DQ9i21dpA=": "iVBORw0KGgoAAAANSUhEUgAABRYAAALYCAYAAAAJnq6UAAAMPmlDQ1BJQ0MgUHJvZmlsZQAASImVVwdYU8kWnluSkJAQIICAlNCbICIlgJQQWugdwUZIAoQSYyCo2NFFBdcuFrChqyIKVkDsiJ1FsffFgoKyLhbsypsU0HVf+d75vrn3v/+c+c+Zc+eWAYB+gieR5KKaAOSJC6RxIQHM0SmpTFIXQAAdUAEKDHj8fAk7JiYCQBs4/93e3YDe0K46yrX+2f9fTUsgzOcDgMRAnC7I5+dBfAAAvJIvkRYAQJTzFpMLJHIMG9CRwgQhXiDHmUpcKcfpSrxH4ZMQx4G4BQA1Ko8nzQRA4zLkmYX8TKih0Quxs1ggEgNAZ0Lsm5c3UQBxGsS20EcCsVyflf6DTubfNNMHNXm8zEGsnIvC1AJF+ZJc3tT/sxz/2/JyZQMxrGGjZklD4+RzhnW7lTMxXI6pEPeI06OiIdaG+INIoPCHGKVkyUITlf6oET+fA2sG9CB2FvACwyE2gjhYnBsVoeLTM0TBXIjhCkGniAq4CRDrQ7xAmB8Ur/LZJJ0Yp4qF1mdIOWwVf44nVcSVx3ogy0lkq/RfZwm5Kn1MoygrIRliCsSWhaKkKIg1IHbKz4kPV/mMKsriRA34SGVx8vwtIY4TikMClPpYYYY0OE7lX5qXPzBfbFOWiBulwvsKshJClfXBWvg8Rf5wLthloZidOKAjzB8dMTAXgTAwSDl3rEsoToxX6XyQFATEKcfiFElujMofNxfmhsh5c4hd8wvjVWPxpAK4IJX6eIakICZBmSdelM0Li1Hmgy8FEYADAgETyGBLBxNBNhC19TT0wCtlTzDgASnIBELgqGIGRiQresTwGA+KwJ8QCUH+4LgARa8QFEL+6yCrPDqCDEVvoWJEDngKcR4IB7nwWqYYJR6MlgSeQEb0j+g82Pgw31zY5P3/nh9gvzNsyESoGNlARCZ9wJMYRAwkhhKDiXa4Ie6Le+MR8OgPmwvOwj0H5vHdn/CU0E54RLhO6CDcniAqlv6UZSTogPrBqlqk/1gL3BpquuEBuA9Uh8q4Hm4IHHFXGIeN+8HIbpDlqPKWV4X5k/bfZvDD3VD5kZ3JKHkI2Z9s+/NIDXsNt0EVea1/rI8y1/TBenMGe36Oz/mh+gJ4Dv/ZE1uA7cfOYiex89gRrAEwseNYI9aKHZXjwdX1RLG6BqLFKfLJgTqif8QbuLPySuY71zh3O39R9hUIp8jf0YAzUTJVKsrMKmCy4RdByOSK+U7DmC7OLq4AyL8vytfXm1jFdwPRa/3Ozf0DAJ/j/f39h79zYccB2OsBH/9D3zlbFvx0qANw7hBfJi1Ucrj8QIBvCTp80gyACbAAtnA+LsAdeAN/EATCQDRIAClgPMw+C65zKZgMpoM5oASUgaVgFVgHNoItYAfYDfaBBnAEnARnwEVwGVwHd+Hq6QQvQC94Bz4jCEJCaAgDMUBMESvEAXFBWIgvEoREIHFICpKGZCJiRIZMR+YiZchyZB2yGalG9iKHkJPIeaQduY08RLqR18gnFEOpqA5qjFqjw1EWykbD0QR0HJqJTkKL0HnoYnQNWoXuQuvRk+hF9Dragb5A+zCAqWN6mBnmiLEwDhaNpWIZmBSbiZVi5VgVVos1wft8FevAerCPOBFn4EzcEa7gUDwR5+OT8Jn4InwdvgOvx1vwq/hDvBf/RqARjAgOBC8ClzCakEmYTCghlBO2EQ4STsNnqZPwjkgk6hFtiB7wWUwhZhOnERcR1xPriCeI7cTHxD4SiWRAciD5kKJJPFIBqYS0lrSLdJx0hdRJ+qCmrmaq5qIWrJaqJlYrVitX26l2TO2K2jO1z2RNshXZixxNFpCnkpeQt5KbyJfIneTPFC2KDcWHkkDJpsyhrKHUUk5T7lHeqKurm6t7qseqi9Rnq69R36N+Tv2h+keqNtWeyqGOpcqoi6nbqSeot6lvaDSaNc2flkoroC2mVdNO0R7QPmgwNJw0uBoCjVkaFRr1Glc0XtLJdCs6mz6eXkQvp++nX6L3aJI1rTU5mjzNmZoVmoc0b2r2aTG0RmhFa+VpLdLaqXVeq0ubpG2tHaQt0J6nvUX7lPZjBsawYHAYfMZcxlbGaUanDlHHRoerk61TprNbp02nV1db11U3SXeKboXuUd0OPUzPWo+rl6u3RG+f3g29T0OMh7CHCIcsHFI75MqQ9/pD9f31hfql+nX61/U/GTANggxyDJYZNBjcN8QN7Q1jDScbbjA8bdgzVGeo91D+0NKh+4beMUKN7I3ijKYZbTFqNeozNjEOMZYYrzU+Zdxjomfib5JtstLkmEm3KcPU11RkutL0uOlzpi6TzcxlrmG2MHvNjMxCzWRmm83azD6b25gnmheb15nft6BYsCwyLFZaNFv0WppaRlpOt6yxvGNFtmJZZVmttjpr9d7axjrZer51g3WXjb4N16bIpsbmni3N1s92km2V7TU7oh3LLsduvd1le9TezT7LvsL+kgPq4O4gcljv0D6MMMxzmHhY1bCbjlRHtmOhY43jQyc9pwinYqcGp5fDLYenDl82/Ozwb85uzrnOW53vjtAeETaieETTiNcu9i58lwqXayNpI4NHzhrZOPKVq4Or0HWD6y03hluk23y3Zrev7h7uUvda924PS480j0qPmywdVgxrEeucJ8EzwHOW5xHPj17uXgVe+7z+8nb0zvHe6d01ymaUcNTWUY99zH14Ppt9OnyZvmm+m3w7/Mz8eH5Vfo/8LfwF/tv8n7Ht2NnsXeyXAc4B0oCDAe85XpwZnBOBWGBIYGlgW5B2UGLQuqAHwebBmcE1wb0hbiHTQk6EEkLDQ5eF3uQac/ncam5vmEfYjLCWcGp4fPi68EcR9hHSiKZINDIsckXkvSirKHFUQzSI5kaviL4fYxMzKeZwLDE2JrYi9mnciLjpcWfjGfET4nfGv0sISFiScDfRNlGW2JxETxqbVJ30PjkweXlyx+jho2eMvphimCJKaUwlpSalbkvtGxM0ZtWYzrFuY0vG3hhnM27KuPPjDcfnjj86gT6BN2F/GiEtOW1n2hdeNK+K15fOTa9M7+Vz+Kv5LwT+gpWCbqGPcLnwWYZPxvKMrkyfzBWZ3Vl+WeVZPSKOaJ3oVXZo9sbs9znROdtz+nOTc+vy1PLS8g6JtcU54paJJhOnTGyXOEhKJB2TvCatmtQrDZduy0fyx+U3FujAH/lWma3sF9nDQt/CisIPk5Mm75+iNUU8pXWq/dSFU58VBRf9Ng2fxp/WPN1s+pzpD2ewZ2yeicxMn9k8y2LWvFmds0Nm75hDmZMz5/di5+LlxW/nJs9tmmc8b/a8x7+E/FJTolEiLbk533v+xgX4AtGCtoUjF65d+K1UUHqhzLmsvOzLIv6iC7+O+HXNr/2LMxa3LXFfsmEpcal46Y1lfst2LNdaXrT88YrIFfUrmStLV75dNWHV+XLX8o2rKatlqzvWRKxpXGu5dunaL+uy1l2vCKioqzSqXFj5fr1g/ZUN/htqNxpvLNv4aZNo063NIZvrq6yryrcQtxRuebo1aevZ31i/VW8z3Fa27et28faOHXE7Wqo9qqt3Gu1cUoPWyGq6d43ddXl34O7GWsfazXV6dWV7wB7Znud70/be2Be+r3k/a3/tAasDlQcZB0vrkfqp9b0NWQ0djSmN7YfCDjU3eTcdPOx0ePsRsyMVR3WPLjlGOTbvWP/xouN9JyQnek5mnnzcPKH57qnRp661xLa0nQ4/fe5M8JlTZ9lnj5/zOXfkvNf5QxdYFxouul+sb3VrPfi72+8H29zb6i95XGq87Hm5qX1U+7ErfldOXg28euYa99rF61HX228k3rh1c+zNjluCW123c2+/ulN45/Pd2fcI90rva94vf2D0oOoPuz/qOtw7jj4MfNj6KP7R3cf8xy+e5D/50jnvKe1p+TPTZ9VdLl1HuoO7Lz8f87zzheTF556SP7X+rHxp+/LAX/5/tfaO7u18JX3V/3rRG4M329+6vm3ui+l78C7v3ef3pR8MPuz4yPp49lPyp2efJ38hfVnz1e5r07fwb/f68/r7JTwpT/ErgMGGZmQA8Ho7ALQUABhwf0YZo9z/KQxR7lkVCPwnrNwjKswdgFr4/x7bA/9ubgKwZyvcfkF9+lgAYmgAJHgCdOTIwTawV1PsK+VGhPuATTFf0/PSwb8x5Z7zh7x/PgO5qiv4+fwv6CJ8Q+JJh9YAAABsZVhJZk1NACoAAAAIAAQBGgAFAAAAAQAAAD4BGwAFAAAAAQAAAEYBKAADAAAAAQACAACHaQAEAAAAAQAAAE4AAAAAAAAAkAAAAAEAAACQAAAAAQACoAIABAAAAAEAAAUWoAMABAAAAAEAAALYAAAAAIkcTAoAAAAJcEhZcwAAFiUAABYlAUlSJPAAAEAASURBVHgB7N15sCZVff/xVnBDhlUWWX4iqyKowYVNREUEAdHSJJWoFVKpVKqslJV/1GipMSWJiSlNghjDpggEBUTFFQEVcY2yKCLqsO+rrDOAcf3xbvg8fudMP3fuc+fOzL1z313Vc06fPn26+/U8gPPx9NOP+f3DS+eigAIKKKCAAgoooIACCiiggAIKKKCAAgpMIPDYCfraVQEFFFBAAQUUUEABBRRQQAEFFFBAAQUU6AUMFv0iKKCAAgoooIACCiiggAIKKKCAAgoooMDEAgaLE5N5gAIKKKCAAgoooIACCiiggAIKKKCAAgoYLPodUEABBRRQQAEFFFBAAQUUUEABBRRQQIGJBQwWJybzAAUUUEABBRRQQAEFFFBAAQUUUEABBRQwWPQ7oIACCiiggAIKKKCAAgoooIACCiiggAITCxgsTkzmAQoooIACCiiggAIKKKCAAgoooIACCihgsOh3QAEFFFBAAQUUUEABBRRQQAEFFFBAAQUmFjBYnJjMAxLine truncated
|
|
||||||
"HWvCItS78DzPGbwcuaGcfkpVDUvL98IvH5SIK8-AcL8=": "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 truncated
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "info",
|
|
||||||
"id": "dc61f2e3-a973-432f-a463-164a15cfc778",
|
|
||||||
"pageVersion": 2,
|
|
||||||
"workspaceVersion": 2,
|
|
||||||
"properties": {
|
|
||||||
"tags": {
|
|
||||||
"options": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pages": [
|
|
||||||
{
|
|
||||||
"id": "W-d9_llZ6rE-qoTiHKTk4",
|
|
||||||
"createDate": 1706862386590,
|
|
||||||
"tags": [],
|
|
||||||
"favorite": false,
|
|
||||||
"title": "Write, Draw, Plan all at Once.",
|
|
||||||
"updatedDate": 1709110332309
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -4,11 +4,11 @@
|
|||||||
"sideEffect": false,
|
"sideEffect": false,
|
||||||
"version": "0.14.0",
|
"version": "0.14.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "node ./build.mjs && node ./build-edgeless.mjs"
|
"postinstall": "node ./build-edgeless.mjs"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./templates.gen.ts",
|
"./onboarding.zip": "./onboarding/onboarding.zip",
|
||||||
"./edgeless": "./edgeless-templates.gen.ts",
|
"./edgeless": "./edgeless-templates.gen.ts",
|
||||||
"./build-edgeless": "./build-edgeless.mjs"
|
"./build-edgeless": "./build-edgeless.mjs"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
/* eslint-disable simple-import-sort/imports */
|
|
||||||
// Auto generated, do not edit manually
|
|
||||||
import json_0 from './onboarding/info.json';
|
|
||||||
import json_1 from './onboarding/blob.json';
|
|
||||||
import json_2 from './onboarding/W-d9_llZ6rE-qoTiHKTk4.snapshot.json';
|
|
||||||
|
|
||||||
export const onboarding = {
|
|
||||||
'info.json': json_0,
|
|
||||||
'blob.json': json_1,
|
|
||||||
'W-d9_llZ6rE-qoTiHKTk4.snapshot.json': json_2
|
|
||||||
}
|
|
||||||
@@ -76,12 +76,6 @@ export class CloudWorkspaceListProvider implements WorkspaceListProvider {
|
|||||||
): Promise<WorkspaceMetadata> {
|
): Promise<WorkspaceMetadata> {
|
||||||
const tempId = nanoid();
|
const tempId = nanoid();
|
||||||
|
|
||||||
const docCollection = new DocCollection({
|
|
||||||
id: tempId,
|
|
||||||
idGenerator: () => nanoid(),
|
|
||||||
schema: globalBlockSuiteSchema,
|
|
||||||
});
|
|
||||||
|
|
||||||
// create workspace on cloud, get workspace id
|
// create workspace on cloud, get workspace id
|
||||||
const {
|
const {
|
||||||
createWorkspace: { id: workspaceId },
|
createWorkspace: { id: workspaceId },
|
||||||
@@ -97,6 +91,19 @@ export class CloudWorkspaceListProvider implements WorkspaceListProvider {
|
|||||||
? new SqliteDocStorage(workspaceId)
|
? new SqliteDocStorage(workspaceId)
|
||||||
: new IndexedDBDocStorage(workspaceId);
|
: new IndexedDBDocStorage(workspaceId);
|
||||||
|
|
||||||
|
const docCollection = new DocCollection({
|
||||||
|
id: tempId,
|
||||||
|
idGenerator: () => nanoid(),
|
||||||
|
schema: globalBlockSuiteSchema,
|
||||||
|
blobStorages: [
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
crud: blobStorage,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
// apply initial state
|
// apply initial state
|
||||||
await initial(docCollection, blobStorage);
|
await initial(docCollection, blobStorage);
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,13 @@ export class LocalWorkspaceListProvider implements WorkspaceListProvider {
|
|||||||
id: id,
|
id: id,
|
||||||
idGenerator: () => nanoid(),
|
idGenerator: () => nanoid(),
|
||||||
schema: globalBlockSuiteSchema,
|
schema: globalBlockSuiteSchema,
|
||||||
|
blobStorages: [
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
crud: blobStorage,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
// apply initial state
|
// apply initial state
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ export const createConfiguration: (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(png|jpg|gif|svg|webp|mp4)$/,
|
test: /\.(png|jpg|gif|svg|webp|mp4|zip)$/,
|
||||||
type: 'asset/resource',
|
type: 'asset/resource',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user