mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-06 17:43:51 +00:00
Compare commits
26 Commits
v0.8.0-bet
...
v0.8.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c78e7983f3 | ||
|
|
10aaaeb1d7 | ||
|
|
13323bcbc0 | ||
|
|
06455bee5e | ||
|
|
aa40d4be8f | ||
|
|
448496c245 | ||
|
|
92714a588b | ||
|
|
d5d73db4d6 | ||
|
|
3d887abefc | ||
|
|
14d0c8ba30 | ||
|
|
391ca0b934 | ||
|
|
3a9265b280 | ||
|
|
4f93e7dbc8 | ||
|
|
e4543ef3b7 | ||
|
|
b7f024eeb2 | ||
|
|
ebc98002ba | ||
|
|
9a89c08fd1 | ||
|
|
d749e8a284 | ||
|
|
0b54d82ddb | ||
|
|
a76d99381d | ||
|
|
d89be5804f | ||
|
|
3ddc76a703 | ||
|
|
9d6d5594b5 | ||
|
|
96f3bbd484 | ||
|
|
561970f7ff | ||
|
|
357b403073 |
@@ -21,6 +21,7 @@
|
||||
"native",
|
||||
"templates",
|
||||
"y-indexeddb",
|
||||
"y-provider",
|
||||
"debug",
|
||||
"storage",
|
||||
"infra",
|
||||
|
||||
45
.github/workflows/nightly-build.yml
vendored
45
.github/workflows/nightly-build.yml
vendored
@@ -73,34 +73,27 @@ jobs:
|
||||
make-distribution:
|
||||
environment: production
|
||||
strategy:
|
||||
# all combinations: macos-latest x64, macos-latest arm64, windows-latest x64, ubuntu-latest x64
|
||||
# all combinations: macos-latest x64, macos-latest arm64, ubuntu-latest x64
|
||||
# For windows, we need a separate approach
|
||||
matrix:
|
||||
spec:
|
||||
- {
|
||||
os: macos-latest,
|
||||
platform: darwin,
|
||||
arch: x64,
|
||||
target: x86_64-apple-darwin,
|
||||
}
|
||||
- {
|
||||
os: macos-latest,
|
||||
platform: darwin,
|
||||
arch: arm64,
|
||||
target: aarch64-apple-darwin,
|
||||
}
|
||||
- {
|
||||
os: ubuntu-latest,
|
||||
platform: linux,
|
||||
arch: x64,
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
}
|
||||
- {
|
||||
os: windows-latest,
|
||||
platform: win32,
|
||||
arch: x64,
|
||||
target: x86_64-pc-windows-msvc,
|
||||
}
|
||||
runs-on: ${{ matrix.spec.os }}
|
||||
- runner: macos-latest
|
||||
platform: darwin
|
||||
arch: x64
|
||||
target: x86_64-apple-darwin
|
||||
- runner: macos-latest
|
||||
platform: darwin
|
||||
arch: arm64
|
||||
target: aarch64-apple-darwin
|
||||
- runner: ubuntu-latest
|
||||
platform: linux
|
||||
arch: x64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- runner: windows-latest
|
||||
platform: win32
|
||||
arch: x64
|
||||
target: x86_64-pc-windows-msvc
|
||||
runs-on: ${{ matrix.spec.runner }}
|
||||
needs:
|
||||
- before-make
|
||||
- set-build-version
|
||||
|
||||
1
.github/workflows/release-desktop-app.yml
vendored
1
.github/workflows/release-desktop-app.yml
vendored
@@ -360,7 +360,6 @@ jobs:
|
||||
./*.zip
|
||||
./*.dmg
|
||||
./*.exe
|
||||
./RELEASES
|
||||
./*.AppImage
|
||||
./*.apk
|
||||
./*.yml
|
||||
|
||||
28
README.md
28
README.md
@@ -146,14 +146,42 @@ Thanks a lot to the community for providing such powerful and simple libraries,
|
||||
|
||||
# Contributors
|
||||
|
||||
## Current Core members
|
||||
|
||||
Team members who are currently maintaining the project:
|
||||
|
||||
- [JimmFly](https://github.com/JimmFly) - Jinfei Yang <yangjinfei001@gmail.com> (he/him)
|
||||
- [pengx17](https://github.com/pengx17) - Peng Xiao <pengxiao@outlook.com> (he/him)
|
||||
- [QiShaoXuan](https://github.com/QiSHaoXuan) - Shaoxuan Qi <qishaoxuan777@gmail.com> (he/him)
|
||||
- [himself65](https://github.com/himself65) - Zeyu "Alex" Yang <himself65@outlook.com> (he/him)
|
||||
|
||||
## All Contributors
|
||||
|
||||
We would like to express our gratitude to all the individuals who have already contributed to AFFiNE! If you have any AFFiNE-related project, documentation, tool or template, please feel free to contribute it by submitting a pull request to our curated list on GitHub: [awesome-affine](https://github.com/toeverything/awesome-affine).
|
||||
|
||||
<a href="https://github.com/toeverything/affine/graphs/contributors">
|
||||
<img alt="contributors" src="https://opencollective.com/affine/contributors.svg?width=890&button=false" />
|
||||
</a>
|
||||
|
||||
## Data Compatibility
|
||||
|
||||
Data compatibility is a very important issue for us. We will try our best to ensure that the data is compatible with the previous version.
|
||||
|
||||
If you encounter any problems when upgrading the version, please feel free to [contact us](mailto:developer@toeverything.info).
|
||||
|
||||
| AFFiNE Version | Export/Import workspace | Data auto migration |
|
||||
| -------------- | ----------------------- | ------------------- |
|
||||
| <= 0.5.4 | ❌️ | ❌ |
|
||||
| 0.6.x | ✅️ | ✅ |
|
||||
| 0.7.x | ✅️ | ✅ |
|
||||
| 0.8.x | ✅ | ✅ |
|
||||
|
||||
## Self-Host
|
||||
|
||||
> We know that the self-host version has been out of date for a long time.
|
||||
>
|
||||
> We are working hard to get this updated to the latest version, you can try our desktop version first.
|
||||
|
||||
Get started with Docker and deploy your own feature-rich, restriction-free deployment of AFFiNE.
|
||||
We are working hard to get this updated to the latest version, you can keep an eye on the [latest packages].
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
|
||||
enableTestProperties: false,
|
||||
enableBroadcastChannelProvider: true,
|
||||
enableDebugPage: true,
|
||||
changelogUrl: 'https://affine.pro/blog/what-is-new-affine-0818',
|
||||
changelogUrl: 'https://affine.pro/blog/affine-080-launch-week-day5',
|
||||
imageProxyUrl: 'https://workers.toeverything.workers.dev/proxy/image',
|
||||
enablePreloading: true,
|
||||
enableNewSettingModal: true,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@affine/core",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"scripts": {
|
||||
"build": "yarn -T run build-core",
|
||||
"dev": "yarn -T run dev-core",
|
||||
@@ -24,13 +24,13 @@
|
||||
"@affine/jotai": "workspace:*",
|
||||
"@affine/templates": "workspace:*",
|
||||
"@affine/workspace": "workspace:*",
|
||||
"@blocksuite/block-std": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/block-std": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/icons": "^2.1.31",
|
||||
"@blocksuite/lit": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@dnd-kit/core": "^6.0.8",
|
||||
"@dnd-kit/sortable": "^7.0.2",
|
||||
"@emotion/cache": "^11.11.0",
|
||||
|
||||
@@ -22,6 +22,7 @@ import { nanoid } from '@blocksuite/store';
|
||||
import { useStaticBlockSuiteWorkspace } from '@toeverything/infra/__internal__/react';
|
||||
import { getCurrentStore } from '@toeverything/infra/atom';
|
||||
import { buildShowcaseWorkspace } from '@toeverything/infra/blocksuite';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { setPageModeAtom } from '../../atoms';
|
||||
import {
|
||||
@@ -91,7 +92,7 @@ export const LocalAdapter: WorkspaceAdapter<WorkspaceFlavour.LOCAL> = {
|
||||
<>
|
||||
<PageDetailEditor
|
||||
pageId={currentPageId}
|
||||
onInit={initEmptyPage}
|
||||
onInit={useCallback(async page => initEmptyPage(page), [])}
|
||||
onLoad={onLoadEditor}
|
||||
workspace={workspace}
|
||||
/>
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
import {
|
||||
migrateDatabaseBlockTo3,
|
||||
migrateToSubdoc,
|
||||
} from '@affine/env/blocksuite';
|
||||
import { setupGlobal } from '@affine/env/global';
|
||||
import type {
|
||||
LocalIndexedDBDownloadProvider,
|
||||
WorkspaceAdapter,
|
||||
} from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace';
|
||||
import type { WorkspaceAdapter } from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import type { RootWorkspaceMetadata } from '@affine/workspace/atom';
|
||||
import {
|
||||
type RootWorkspaceMetadataV2,
|
||||
rootWorkspacesMetadataAtom,
|
||||
workspaceAdaptersAtom,
|
||||
} from '@affine/workspace/atom';
|
||||
import { globalBlockSuiteSchema } from '@affine/workspace/manager';
|
||||
import {
|
||||
getOrCreateWorkspace,
|
||||
globalBlockSuiteSchema,
|
||||
} from '@affine/workspace/manager';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
import {
|
||||
migrateLocalBlobStorage,
|
||||
upgradeV1ToV2,
|
||||
} from '@affine/workspace/migration';
|
||||
import { createIndexedDBDownloadProvider } from '@affine/workspace/providers';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
migrateWorkspace,
|
||||
WorkspaceVersion,
|
||||
} from '@toeverything/infra/blocksuite';
|
||||
import { downloadBinary } from '@toeverything/y-indexeddb';
|
||||
import type { createStore } from 'jotai/vanilla';
|
||||
import { Doc } from 'yjs';
|
||||
import { applyUpdate } from 'yjs';
|
||||
|
||||
import { WorkspaceAdapters } from '../adapters/workspace';
|
||||
|
||||
@@ -33,94 +33,57 @@ async function tryMigration() {
|
||||
const promises: Promise<void>[] = [];
|
||||
const newMetadata = [...metadata];
|
||||
metadata.forEach(oldMeta => {
|
||||
if (!('version' in oldMeta)) {
|
||||
const adapter = WorkspaceAdapters[oldMeta.flavour];
|
||||
assertExists(adapter);
|
||||
const upgrade = async () => {
|
||||
if (oldMeta.flavour !== WorkspaceFlavour.LOCAL) {
|
||||
console.warn('not supported');
|
||||
return;
|
||||
}
|
||||
const workspace = await adapter.CRUD.get(oldMeta.id);
|
||||
if (!workspace) {
|
||||
console.warn('cannot find workspace', oldMeta.id);
|
||||
return;
|
||||
}
|
||||
const doc = workspace.blockSuiteWorkspace.doc;
|
||||
const provider = createIndexedDBDownloadProvider(
|
||||
workspace.id,
|
||||
doc,
|
||||
{
|
||||
awareness:
|
||||
workspace.blockSuiteWorkspace.awarenessStore.awareness,
|
||||
}
|
||||
) as LocalIndexedDBDownloadProvider;
|
||||
provider.sync();
|
||||
await provider.whenReady;
|
||||
const newDoc = migrateToSubdoc(doc);
|
||||
if (doc === newDoc) {
|
||||
console.log('doc not changed');
|
||||
return;
|
||||
}
|
||||
const newWorkspace = upgradeV1ToV2(workspace);
|
||||
await migrateDatabaseBlockTo3(
|
||||
newWorkspace.blockSuiteWorkspace.doc,
|
||||
globalBlockSuiteSchema
|
||||
);
|
||||
|
||||
const newId = await adapter.CRUD.create(
|
||||
newWorkspace.blockSuiteWorkspace
|
||||
);
|
||||
|
||||
await adapter.CRUD.delete(workspace as any);
|
||||
console.log('migrated', oldMeta.id, newId);
|
||||
const index = newMetadata.findIndex(meta => meta.id === oldMeta.id);
|
||||
newMetadata[index] = {
|
||||
...oldMeta,
|
||||
id: newId,
|
||||
version: WorkspaceVersion.DatabaseV3,
|
||||
};
|
||||
await migrateLocalBlobStorage(workspace.id, newId);
|
||||
console.log('migrate to v2');
|
||||
};
|
||||
|
||||
// create a new workspace and push it to metadata
|
||||
promises.push(upgrade());
|
||||
} else if (oldMeta.version < WorkspaceVersion.DatabaseV3) {
|
||||
const adapter = WorkspaceAdapters[oldMeta.flavour];
|
||||
assertExists(adapter);
|
||||
if (oldMeta.flavour === WorkspaceFlavour.LOCAL) {
|
||||
promises.push(
|
||||
(async () => {
|
||||
if (oldMeta.flavour !== WorkspaceFlavour.LOCAL) {
|
||||
console.warn('not supported');
|
||||
return;
|
||||
migrateWorkspace(
|
||||
'version' in oldMeta ? oldMeta.version : undefined,
|
||||
{
|
||||
getCurrentRootDoc: async () => {
|
||||
const doc = new Doc({
|
||||
guid: oldMeta.id,
|
||||
});
|
||||
const downloadWorkspace = async (doc: Doc): Promise<void> => {
|
||||
const binary = await downloadBinary(doc.guid);
|
||||
if (binary) {
|
||||
applyUpdate(doc, binary);
|
||||
}
|
||||
return Promise.all(
|
||||
[...doc.subdocs.values()].map(subdoc =>
|
||||
downloadWorkspace(subdoc)
|
||||
)
|
||||
).then();
|
||||
};
|
||||
await downloadWorkspace(doc);
|
||||
return doc;
|
||||
},
|
||||
createWorkspace: async () =>
|
||||
getOrCreateWorkspace(nanoid(), WorkspaceFlavour.LOCAL),
|
||||
getSchema: () => globalBlockSuiteSchema,
|
||||
}
|
||||
const workspace = await adapter.CRUD.get(oldMeta.id);
|
||||
if (workspace) {
|
||||
const provider = createIndexedDBDownloadProvider(
|
||||
workspace.id,
|
||||
workspace.blockSuiteWorkspace.doc,
|
||||
{
|
||||
awareness:
|
||||
workspace.blockSuiteWorkspace.awarenessStore.awareness,
|
||||
}
|
||||
) as LocalIndexedDBDownloadProvider;
|
||||
provider.sync();
|
||||
await provider.whenReady;
|
||||
await migrateDatabaseBlockTo3(
|
||||
workspace.blockSuiteWorkspace.doc,
|
||||
globalBlockSuiteSchema
|
||||
).then(async workspace => {
|
||||
if (typeof workspace !== 'boolean') {
|
||||
const adapter = WorkspaceAdapters[oldMeta.flavour];
|
||||
const oldWorkspace = await adapter.CRUD.get(oldMeta.id);
|
||||
const newId = await adapter.CRUD.create(workspace);
|
||||
assertExists(
|
||||
oldWorkspace,
|
||||
'workspace should exist after migrate'
|
||||
);
|
||||
await adapter.CRUD.delete(oldWorkspace.blockSuiteWorkspace);
|
||||
const index = newMetadata.findIndex(
|
||||
meta => meta.id === oldMeta.id
|
||||
);
|
||||
newMetadata[index] = {
|
||||
...oldMeta,
|
||||
id: newId,
|
||||
version: WorkspaceVersion.DatabaseV3,
|
||||
};
|
||||
await migrateLocalBlobStorage(workspace.id, newId);
|
||||
console.log('workspace migrated', oldMeta.id, newId);
|
||||
} else if (workspace) {
|
||||
console.log('workspace migrated', oldMeta.id);
|
||||
}
|
||||
const index = newMetadata.findIndex(
|
||||
meta => meta.id === oldMeta.id
|
||||
);
|
||||
newMetadata[index] = {
|
||||
...oldMeta,
|
||||
version: WorkspaceVersion.DatabaseV3,
|
||||
};
|
||||
console.log('migrate to v3');
|
||||
})()
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import { initEmptyPage } from '@affine/env/blocksuite';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { getOrCreateWorkspace } from '@affine/workspace/manager';
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { BlockSuiteEditor } from '../../blocksuite/block-suite-editor';
|
||||
|
||||
const blockSuiteWorkspace = getOrCreateWorkspace(
|
||||
'test',
|
||||
WorkspaceFlavour.LOCAL
|
||||
);
|
||||
|
||||
const page = blockSuiteWorkspace.createPage({ id: 'page0' });
|
||||
|
||||
const Editor = () => {
|
||||
const onLoad = useCallback((page: Page, editor: EditorContainer) => {
|
||||
// @ts-expect-error
|
||||
globalThis.page = page;
|
||||
// @ts-expect-error
|
||||
globalThis.editor = editor;
|
||||
return () => void 0;
|
||||
}, []);
|
||||
|
||||
if (!page) {
|
||||
return <>loading...</>;
|
||||
}
|
||||
return (
|
||||
<BlockSuiteEditor
|
||||
page={page}
|
||||
mode="page"
|
||||
onInit={initEmptyPage}
|
||||
onLoad={onLoad}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Editor;
|
||||
@@ -146,9 +146,11 @@ export const BlockSuitePageList = ({
|
||||
const tagOptionMap = useMemo(
|
||||
() =>
|
||||
Object.fromEntries(
|
||||
blockSuiteWorkspace.meta.properties.tags.options.map(v => [v.id, v])
|
||||
(
|
||||
blockSuiteWorkspace.meta.properties.tags ?? { options: [] }
|
||||
).options.map(v => [v.id, v])
|
||||
),
|
||||
[blockSuiteWorkspace.meta.properties.tags.options]
|
||||
[blockSuiteWorkspace.meta.properties.tags]
|
||||
);
|
||||
const list = useMemo(
|
||||
() =>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { initEmptyPage } from '@affine/env/blocksuite';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import type { PageBlockModel } from '@blocksuite/blocks';
|
||||
import { assertEquals } from '@blocksuite/global/utils';
|
||||
import { PlusIcon } from '@blocksuite/icons';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
@@ -39,15 +38,7 @@ export const Footer = ({
|
||||
const id = nanoid();
|
||||
const page = createPage(id);
|
||||
assertEquals(page.id, id);
|
||||
await initEmptyPage(page);
|
||||
const block = page.getBlockByFlavour(
|
||||
'affine:page'
|
||||
)[0] as PageBlockModel;
|
||||
if (block) {
|
||||
block.title.insert(query, 0);
|
||||
} else {
|
||||
console.warn('No page block found');
|
||||
}
|
||||
await initEmptyPage(page, query);
|
||||
blockSuiteWorkspace.setPageMeta(page.id, {
|
||||
title: query,
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Modal, ModalWrapper } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { Command } from 'cmdk';
|
||||
import { startTransition } from 'react';
|
||||
import { startTransition, Suspense } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import type { AllWorkspace } from '../../../shared';
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
StyledModalDivider,
|
||||
StyledModalFooter,
|
||||
StyledModalHeader,
|
||||
StyledNotFound,
|
||||
StyledShortcut,
|
||||
} from './style';
|
||||
|
||||
@@ -41,7 +42,7 @@ export const QuickSearchModal = ({
|
||||
setOpen(false);
|
||||
}, [setOpen]);
|
||||
|
||||
// Add ‘⌘+K’ shortcut keys as switches
|
||||
// Add ‘⌘+K’ shortcut keys as switches
|
||||
useEffect(() => {
|
||||
const keydown = (e: KeyboardEvent) => {
|
||||
if ((e.key === 'k' && e.metaKey) || (e.key === 'k' && e.ctrlKey)) {
|
||||
@@ -131,12 +132,20 @@ export const QuickSearchModal = ({
|
||||
<StyledModalDivider />
|
||||
<Command.List>
|
||||
<StyledContent>
|
||||
<Results
|
||||
query={query}
|
||||
onClose={handleClose}
|
||||
workspace={workspace}
|
||||
setShowCreatePage={setShowCreatePage}
|
||||
/>
|
||||
<Suspense
|
||||
fallback={
|
||||
<StyledNotFound>
|
||||
<span>{t['com.affine.loading']()}</span>
|
||||
</StyledNotFound>
|
||||
}
|
||||
>
|
||||
<Results
|
||||
query={query}
|
||||
onClose={handleClose}
|
||||
workspace={workspace}
|
||||
setShowCreatePage={setShowCreatePage}
|
||||
/>
|
||||
</Suspense>
|
||||
</StyledContent>
|
||||
{showCreatePage ? (
|
||||
<>
|
||||
|
||||
@@ -2,11 +2,13 @@ import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
|
||||
import type { Workspace } from '@blocksuite/store';
|
||||
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper';
|
||||
import { Command } from 'cmdk';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { type Atom, atom, useAtomValue } from 'jotai';
|
||||
import type { Dispatch, SetStateAction } from 'react';
|
||||
import { startTransition, useEffect } from 'react';
|
||||
|
||||
import { recentPageSettingsAtom } from '../../../atoms';
|
||||
import { useNavigateHelper } from '../../../hooks/use-navigate-helper';
|
||||
@@ -20,6 +22,29 @@ export interface ResultsProps {
|
||||
onClose: () => void;
|
||||
setShowCreatePage: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const loadAllPageWeakMap = new WeakMap<Workspace, Atom<Promise<void>>>();
|
||||
|
||||
function getLoadAllPage(workspace: Workspace) {
|
||||
if (loadAllPageWeakMap.has(workspace)) {
|
||||
return loadAllPageWeakMap.get(workspace) as Atom<Promise<void>>;
|
||||
} else {
|
||||
const aAtom = atom(async () => {
|
||||
// fixme: we have to load all pages here and re-index them
|
||||
// there might have performance issue
|
||||
await Promise.all(
|
||||
[...workspace.pages.values()].map(page =>
|
||||
page.waitForLoaded().then(() => {
|
||||
workspace.indexer.search.refreshPageIndex(page.id, page.spaceDoc);
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
loadAllPageWeakMap.set(workspace, aAtom);
|
||||
return aAtom;
|
||||
}
|
||||
}
|
||||
|
||||
export const Results = ({
|
||||
query,
|
||||
workspace,
|
||||
@@ -31,14 +56,20 @@ export const Results = ({
|
||||
const pageList = useBlockSuitePageMeta(blockSuiteWorkspace);
|
||||
assertExists(blockSuiteWorkspace.id);
|
||||
const list = useSwitchToConfig(workspace.id);
|
||||
useAtomValue(getLoadAllPage(blockSuiteWorkspace));
|
||||
|
||||
const recentPageSetting = useAtomValue(recentPageSettingsAtom);
|
||||
const t = useAFFiNEI18N();
|
||||
const { jumpToPage, jumpToSubPath } = useNavigateHelper();
|
||||
const results = blockSuiteWorkspace.search({ query });
|
||||
|
||||
// remove `space:` prefix
|
||||
const pageIds = [...results.values()].map(id => id.slice(6));
|
||||
const pageIds = [...blockSuiteWorkspace.search({ query }).values()].map(
|
||||
id => {
|
||||
if (id.startsWith('space:')) {
|
||||
return id.slice(6);
|
||||
} else {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const resultsPageMeta = pageList.filter(
|
||||
page => pageIds.indexOf(page.id) > -1 && !page.trash
|
||||
@@ -53,7 +84,11 @@ export const Results = ({
|
||||
}
|
||||
});
|
||||
|
||||
setShowCreatePage(resultsPageMeta.length === 0);
|
||||
useEffect(() => {
|
||||
startTransition(() => {
|
||||
setShowCreatePage(resultsPageMeta.length === 0);
|
||||
});
|
||||
}, [resultsPageMeta.length, setShowCreatePage]);
|
||||
|
||||
if (!query) {
|
||||
return (
|
||||
@@ -117,7 +152,12 @@ export const Results = ({
|
||||
return (
|
||||
<StyledNotFound>
|
||||
<span>{t['Find 0 result']()}</span>
|
||||
<image href="/imgs/no-result.svg" width={200} height={200} />
|
||||
<img
|
||||
alt="no result"
|
||||
src="/imgs/no-result.svg"
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
</StyledNotFound>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import type { WorkspaceRegistry } from '@affine/env/workspace';
|
||||
import { WorkspaceVersion } from '@affine/env/workspace';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import { WorkspaceVersion } from '@toeverything/infra/blocksuite';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import { saveWorkspaceToLocalStorage } from '@affine/workspace/local/crud';
|
||||
import { getOrCreateWorkspace } from '@affine/workspace/manager';
|
||||
import { nanoid } from '@blocksuite/store';
|
||||
import { getWorkspace } from '@toeverything/infra/__internal__/workspace';
|
||||
import { getCurrentStore } from '@toeverything/infra/atom';
|
||||
import { buildShowcaseWorkspace } from '@toeverything/infra/blocksuite';
|
||||
import {
|
||||
buildShowcaseWorkspace,
|
||||
WorkspaceVersion,
|
||||
} from '@toeverything/infra/blocksuite';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
|
||||
@@ -33,8 +33,9 @@ import { usePassiveWorkspaceEffect } from '@toeverything/infra/__internal__/reac
|
||||
import { currentWorkspaceIdAtom } from '@toeverything/infra/atom';
|
||||
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
||||
import type { PropsWithChildren, ReactElement } from 'react';
|
||||
import { lazy, Suspense, useCallback, useMemo } from 'react';
|
||||
import { lazy, Suspense, useCallback, useEffect, useMemo } from 'react';
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
import { Map as YMap } from 'yjs';
|
||||
|
||||
import { WorkspaceAdapters } from '../adapters/workspace';
|
||||
import {
|
||||
@@ -150,6 +151,23 @@ export const WorkspaceLayoutInner = ({ children }: PropsWithChildren) => {
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const { openPage } = useNavigateHelper();
|
||||
|
||||
useEffect(() => {
|
||||
// hotfix for blockVersions
|
||||
// this is a mistake in the
|
||||
// 0.8.0 ~ 0.8.1
|
||||
// 0.8.0-beta.0 ~ 0.8.0-beta.3
|
||||
// 0.9.0-canary.0 ~ 0.9.0-canary.3
|
||||
const meta = currentWorkspace.blockSuiteWorkspace.doc.getMap('meta');
|
||||
const blockVersions = meta.get('blockVersions');
|
||||
if (!(blockVersions instanceof YMap)) {
|
||||
console.log('fixing blockVersions');
|
||||
meta.set(
|
||||
'blockVersions',
|
||||
new YMap(Object.entries(blockVersions as Record<string, number>))
|
||||
);
|
||||
}
|
||||
}, [currentWorkspace.blockSuiteWorkspace.doc]);
|
||||
|
||||
usePassiveWorkspaceEffect(currentWorkspace.blockSuiteWorkspace);
|
||||
|
||||
const [, setOpenWorkspacesModal] = useAtom(openWorkspacesModalAtom);
|
||||
|
||||
@@ -23,6 +23,7 @@ export const loader: LoaderFunction = async () => {
|
||||
const target = (lastId && meta.find(({ id }) => id === lastId)) || meta.at(0);
|
||||
if (target) {
|
||||
const targetWorkspace = getWorkspace(target.id);
|
||||
|
||||
const nonTrashPages = targetWorkspace.meta.pageMetas.filter(
|
||||
({ trash }) => !trash
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/docs",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -10,12 +10,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@affine/component": "workspace:*",
|
||||
"@blocksuite/block-std": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/block-std": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"express": "^4.18.2",
|
||||
"jotai": "^2.3.1",
|
||||
"react": "18.3.0-canary-7118f5dd7-20230705",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
owner: toeverything
|
||||
repo: AFFiNE
|
||||
provider: github
|
||||
provider: custom
|
||||
private: false
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/electron",
|
||||
"private": true,
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"author": "affine",
|
||||
"repository": {
|
||||
"url": "https://github.com/toeverything/AFFiNE",
|
||||
@@ -29,10 +29,10 @@
|
||||
"@affine/env": "workspace:*",
|
||||
"@affine/native": "workspace:*",
|
||||
"@affine/sdk": "workspace:*",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@electron-forge/cli": "^6.4.0",
|
||||
"@electron-forge/core": "^6.4.0",
|
||||
"@electron-forge/core-utils": "^6.4.0",
|
||||
@@ -42,6 +42,7 @@
|
||||
"@electron-forge/shared-types": "^6.4.0",
|
||||
"@electron/remote": "2.0.10",
|
||||
"@reforged/maker-appimage": "^3.3.1",
|
||||
"@toeverything/infra": "workspace:*",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"cross-env": "7.0.3",
|
||||
@@ -51,7 +52,10 @@
|
||||
"electron-window-state": "^5.0.3",
|
||||
"esbuild": "^0.19.2",
|
||||
"fs-extra": "^11.1.1",
|
||||
"glob": "^10.3.3",
|
||||
"jotai": "^2.3.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"rxjs": "^7.8.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"undici": "^5.23.0",
|
||||
"uuid": "^9.0.0",
|
||||
@@ -60,13 +64,10 @@
|
||||
"zx": "^7.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@toeverything/infra": "workspace:*",
|
||||
"async-call-rpc": "^6.3.1",
|
||||
"electron-updater": "^6.1.4",
|
||||
"link-preview-js": "^3.0.5",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nanoid": "^4.0.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"yjs": "^13.6.7"
|
||||
},
|
||||
"build": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
owner: toeverything
|
||||
repo: AFFiNE
|
||||
provider: github
|
||||
provider: custom
|
||||
private: false
|
||||
|
||||
@@ -44,6 +44,7 @@ export const config = () => {
|
||||
'electron-updater',
|
||||
'@toeverything/plugin-infra',
|
||||
'yjs',
|
||||
'semver',
|
||||
],
|
||||
define: define,
|
||||
format: 'cjs',
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// do not run in your local machine
|
||||
/* eslint-disable */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const crypto = require('node:crypto');
|
||||
/* eslint-enable */
|
||||
|
||||
const yml = {
|
||||
@@ -10,18 +10,10 @@ const yml = {
|
||||
files: [],
|
||||
};
|
||||
|
||||
let fileList = [];
|
||||
// TODO: maybe add `beta` and `stable`
|
||||
const BUILD_TYPE = process.env.BUILD_TYPE || 'canary';
|
||||
|
||||
const generateYml = async () => {
|
||||
fileList = [
|
||||
`affine-${BUILD_TYPE}-macos-arm64.dmg`,
|
||||
`affine-${BUILD_TYPE}-macos-arm64.zip`,
|
||||
`affine-${BUILD_TYPE}-macos-x64.zip`,
|
||||
`affine-${BUILD_TYPE}-macos-x64.dmg`,
|
||||
];
|
||||
fileList.forEach(fileName => {
|
||||
const generateYml = platform => {
|
||||
const regex = new RegExp(`^affine-.*-${platform}-.*.(exe|zip|dmg|AppImage)$`);
|
||||
const files = fs.readdirSync(__dirname).filter(file => regex.test(file));
|
||||
files.forEach(fileName => {
|
||||
const filePath = path.join(__dirname, './', fileName);
|
||||
try {
|
||||
const fileData = fs.readFileSync(filePath);
|
||||
@@ -58,6 +50,9 @@ const generateYml = async () => {
|
||||
`sha512: ${yml.sha512}\n` +
|
||||
`releaseDate: ${yml.releaseDate}\n`;
|
||||
|
||||
fs.writeFileSync(`./latest-mac.yml`, ymlStr);
|
||||
const fileName = platform === 'windows' ? 'latest.yml' : 'latest-mac.yml';
|
||||
|
||||
fs.writeFileSync(fileName, ymlStr);
|
||||
};
|
||||
generateYml();
|
||||
generateYml('windows');
|
||||
generateYml('macos');
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
arch,
|
||||
buildType,
|
||||
iconUrl,
|
||||
icoPath,
|
||||
platform,
|
||||
productName,
|
||||
ROOT,
|
||||
@@ -45,6 +46,7 @@ async function make() {
|
||||
appDirectory: appDirectory,
|
||||
outputDirectory: outPath,
|
||||
iconUrl: iconUrl,
|
||||
setupIcon: icoPath,
|
||||
loadingGif: path.resolve(ROOT, './resources/icons/affine_installing.gif'),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { equal } from 'node:assert';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
import { migrateToSubdoc } from '@affine/env/blocksuite';
|
||||
import { SqliteConnection } from '@affine/native';
|
||||
import {
|
||||
migrateToSubdoc,
|
||||
WorkspaceVersion,
|
||||
} from '@toeverything/infra/blocksuite';
|
||||
import fs from 'fs-extra';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { applyUpdate, Doc as YDoc, encodeStateAsUpdate } from 'yjs';
|
||||
@@ -30,6 +34,74 @@ export const migrateToSubdocAndReplaceDatabase = async (path: string) => {
|
||||
await db.close();
|
||||
};
|
||||
|
||||
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
||||
import { Schema, Workspace } from '@blocksuite/store';
|
||||
import { migrateWorkspace } from '@toeverything/infra/blocksuite';
|
||||
|
||||
// v1 v2 -> v3
|
||||
export const migrateToLatestDatabase = async (path: string) => {
|
||||
const connection = new SqliteConnection(path);
|
||||
await connection.connect();
|
||||
await connection.initVersion();
|
||||
const schema = new Schema();
|
||||
schema.register(AffineSchemas).register(__unstableSchemas);
|
||||
const rootDoc = new YDoc();
|
||||
const downloadBinary = async (doc: YDoc, isRoot: boolean): Promise<void> => {
|
||||
const update = (
|
||||
await connection.getUpdates(isRoot ? undefined : doc.guid)
|
||||
).map(update => update.data);
|
||||
// Buffer[] -> Uint8Array[]
|
||||
const data = update.map(update => new Uint8Array(update));
|
||||
data.forEach(data => {
|
||||
applyUpdate(doc, data);
|
||||
});
|
||||
// trigger data manually
|
||||
if (isRoot) {
|
||||
doc.getMap('meta');
|
||||
doc.getMap('spaces');
|
||||
} else {
|
||||
doc.getMap('blocks');
|
||||
}
|
||||
await Promise.all(
|
||||
[...doc.subdocs].map(subdoc => {
|
||||
return downloadBinary(subdoc, false);
|
||||
})
|
||||
);
|
||||
};
|
||||
await downloadBinary(rootDoc, true);
|
||||
const result = await migrateWorkspace(WorkspaceVersion.SubDoc, {
|
||||
getSchema: () => schema,
|
||||
getCurrentRootDoc: () => Promise.resolve(rootDoc),
|
||||
createWorkspace: () =>
|
||||
Promise.resolve(
|
||||
new Workspace({
|
||||
id: nanoid(10),
|
||||
schema,
|
||||
blobStorages: [],
|
||||
providerCreators: [],
|
||||
})
|
||||
),
|
||||
});
|
||||
equal(
|
||||
typeof result,
|
||||
'boolean',
|
||||
'migrateWorkspace should return boolean value'
|
||||
);
|
||||
const uploadBinary = async (doc: YDoc, isRoot: boolean) => {
|
||||
await connection.replaceUpdates(doc.guid, [
|
||||
{ docId: isRoot ? undefined : doc.guid, data: encodeStateAsUpdate(doc) },
|
||||
]);
|
||||
// connection..applyUpdate(encodeStateAsUpdate(doc), 'self', doc.guid)
|
||||
await Promise.all(
|
||||
[...doc.subdocs].map(subdoc => {
|
||||
return uploadBinary(subdoc, false);
|
||||
})
|
||||
);
|
||||
};
|
||||
await uploadBinary(rootDoc, true);
|
||||
await connection.close();
|
||||
};
|
||||
|
||||
export const copyToTemp = async (path: string) => {
|
||||
const tmpDirPath = resolve(await mainRPC.getPath('sessionData'), 'tmp');
|
||||
const tmpFilePath = resolve(tmpDirPath, nanoid());
|
||||
|
||||
@@ -12,7 +12,11 @@ import fs from 'fs-extra';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import { ensureSQLiteDB } from '../db/ensure-db';
|
||||
import { copyToTemp, migrateToSubdocAndReplaceDatabase } from '../db/migration';
|
||||
import {
|
||||
copyToTemp,
|
||||
migrateToLatestDatabase,
|
||||
migrateToSubdocAndReplaceDatabase,
|
||||
} from '../db/migration';
|
||||
import type { WorkspaceSQLiteDB } from '../db/workspace-db-adapter';
|
||||
import { logger } from '../logger';
|
||||
import { mainRPC } from '../main-rpc';
|
||||
@@ -197,7 +201,22 @@ export async function loadDBFile(): Promise<LoadDBFileResult> {
|
||||
}
|
||||
}
|
||||
|
||||
if (validationResult === ValidationResult.MissingVersionColumn) {
|
||||
try {
|
||||
const tmpDBPath = await copyToTemp(originalPath);
|
||||
await migrateToLatestDatabase(tmpDBPath);
|
||||
originalPath = tmpDBPath;
|
||||
} catch (error) {
|
||||
logger.warn(
|
||||
`loadDBFile, migration version column failed: ${originalPath}`,
|
||||
error
|
||||
);
|
||||
return { error: 'DB_FILE_MIGRATION_FAILED' };
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
validationResult !== ValidationResult.MissingVersionColumn &&
|
||||
validationResult !== ValidationResult.MissingDocIdColumn &&
|
||||
validationResult !== ValidationResult.Valid
|
||||
) {
|
||||
|
||||
250
apps/electron/src/main/updater/custom-github-provider.ts
Normal file
250
apps/electron/src/main/updater/custom-github-provider.ts
Normal file
@@ -0,0 +1,250 @@
|
||||
// credits: migrated from https://github.com/electron-userland/electron-builder/blob/master/packages/electron-updater/src/providers/GitHubProvider.ts
|
||||
import type {
|
||||
CustomPublishOptions,
|
||||
GithubOptions,
|
||||
ReleaseNoteInfo,
|
||||
XElement,
|
||||
} from 'builder-util-runtime';
|
||||
import { HttpError, newError, parseXml } from 'builder-util-runtime';
|
||||
import {
|
||||
type AppUpdater,
|
||||
CancellationToken,
|
||||
type ResolvedUpdateFileInfo,
|
||||
type UpdateInfo,
|
||||
} from 'electron-updater';
|
||||
import { BaseGitHubProvider } from 'electron-updater/out/providers/GitHubProvider';
|
||||
import {
|
||||
parseUpdateInfo,
|
||||
type ProviderRuntimeOptions,
|
||||
resolveFiles,
|
||||
} from 'electron-updater/out/providers/Provider';
|
||||
import * as semver from 'semver';
|
||||
|
||||
interface GithubUpdateInfo extends UpdateInfo {
|
||||
tag: string;
|
||||
}
|
||||
|
||||
const hrefRegExp = /\/tag\/([^/]+)$/;
|
||||
|
||||
export class CustomGitHubProvider extends BaseGitHubProvider<GithubUpdateInfo> {
|
||||
constructor(
|
||||
options: CustomPublishOptions,
|
||||
private updater: AppUpdater,
|
||||
runtimeOptions: ProviderRuntimeOptions
|
||||
) {
|
||||
super(options as unknown as GithubOptions, 'github.com', runtimeOptions);
|
||||
}
|
||||
|
||||
async getLatestVersion(): Promise<GithubUpdateInfo> {
|
||||
const cancellationToken = new CancellationToken();
|
||||
|
||||
const feedXml = await this.httpRequest(
|
||||
newUrlFromBase(`${this.basePath}.atom`, this.baseUrl),
|
||||
{
|
||||
accept: 'application/xml, application/atom+xml, text/xml, */*',
|
||||
},
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
if (!feedXml) {
|
||||
throw new Error(
|
||||
`Cannot find feed in the remote server (${this.baseUrl.href})`
|
||||
);
|
||||
}
|
||||
|
||||
const feed = parseXml(feedXml);
|
||||
// noinspection TypeScriptValidateJSTypes
|
||||
const latestRelease = feed.element(
|
||||
'entry',
|
||||
false,
|
||||
`No published versions on GitHub`
|
||||
);
|
||||
let tag: string | null = null;
|
||||
try {
|
||||
const currentChannel =
|
||||
this.options.channel ||
|
||||
this.updater?.channel ||
|
||||
(semver.prerelease(this.updater.currentVersion)?.[0] as string) ||
|
||||
null;
|
||||
|
||||
if (currentChannel === null) {
|
||||
throw newError(
|
||||
`Cannot parse channel from version: ${this.updater.currentVersion}`,
|
||||
'ERR_UPDATER_INVALID_VERSION'
|
||||
);
|
||||
}
|
||||
|
||||
for (const element of feed.getElements('entry')) {
|
||||
// noinspection TypeScriptValidateJSTypes
|
||||
const hrefElement = hrefRegExp.exec(
|
||||
element.element('link').attribute('href')
|
||||
);
|
||||
|
||||
// If this is null then something is wrong and skip this release
|
||||
if (hrefElement === null) continue;
|
||||
|
||||
// This Release's Tag
|
||||
const hrefTag = hrefElement[1];
|
||||
// Get Channel from this release's tag
|
||||
// If it is null, we believe it is stable version
|
||||
const hrefChannel =
|
||||
(semver.prerelease(hrefTag)?.[0] as string) || 'stable';
|
||||
|
||||
const isNextPreRelease = hrefChannel === currentChannel;
|
||||
if (isNextPreRelease) {
|
||||
tag = hrefTag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
throw newError(
|
||||
`Cannot parse releases feed: ${
|
||||
e.stack || e.message
|
||||
},\nXML:\n${feedXml}`,
|
||||
'ERR_UPDATER_INVALID_RELEASE_FEED'
|
||||
);
|
||||
}
|
||||
|
||||
if (tag == null) {
|
||||
throw newError(
|
||||
`No published versions on GitHub`,
|
||||
'ERR_UPDATER_NO_PUBLISHED_VERSIONS'
|
||||
);
|
||||
}
|
||||
|
||||
let rawData: string | null = null;
|
||||
let channelFile = '';
|
||||
let channelFileUrl: any = '';
|
||||
const fetchData = async (channelName: string) => {
|
||||
channelFile = getChannelFilename(channelName);
|
||||
channelFileUrl = newUrlFromBase(
|
||||
this.getBaseDownloadPath(String(tag), channelFile),
|
||||
this.baseUrl
|
||||
);
|
||||
const requestOptions = this.createRequestOptions(channelFileUrl);
|
||||
try {
|
||||
return await this.executor.request(requestOptions, cancellationToken);
|
||||
} catch (e: any) {
|
||||
if (e instanceof HttpError && e.statusCode === 404) {
|
||||
throw newError(
|
||||
`Cannot find ${channelFile} in the latest release artifacts (${channelFileUrl}): ${
|
||||
e.stack || e.message
|
||||
}`,
|
||||
'ERR_UPDATER_CHANNEL_FILE_NOT_FOUND'
|
||||
);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const channel = this.updater.allowPrerelease
|
||||
? this.getCustomChannelName(
|
||||
String(semver.prerelease(tag)?.[0] || 'latest')
|
||||
)
|
||||
: this.getDefaultChannelName();
|
||||
rawData = await fetchData(channel);
|
||||
} catch (e: any) {
|
||||
if (this.updater.allowPrerelease) {
|
||||
// Allow fallback to `latest.yml`
|
||||
rawData = await fetchData(this.getDefaultChannelName());
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
const result = parseUpdateInfo(rawData, channelFile, channelFileUrl);
|
||||
if (result.releaseName == null) {
|
||||
result.releaseName = latestRelease.elementValueOrEmpty('title');
|
||||
}
|
||||
|
||||
if (result.releaseNotes == null) {
|
||||
result.releaseNotes = computeReleaseNotes(
|
||||
this.updater.currentVersion,
|
||||
this.updater.fullChangelog,
|
||||
feed,
|
||||
latestRelease
|
||||
);
|
||||
}
|
||||
return {
|
||||
tag: tag,
|
||||
...result,
|
||||
};
|
||||
}
|
||||
|
||||
private get basePath(): string {
|
||||
return `/${this.options.owner}/${this.options.repo}/releases`;
|
||||
}
|
||||
|
||||
resolveFiles(updateInfo: GithubUpdateInfo): Array<ResolvedUpdateFileInfo> {
|
||||
// still replace space to - due to backward compatibility
|
||||
return resolveFiles(updateInfo, this.baseUrl, p =>
|
||||
this.getBaseDownloadPath(updateInfo.tag, p.replace(/ /g, '-'))
|
||||
);
|
||||
}
|
||||
|
||||
private getBaseDownloadPath(tag: string, fileName: string): string {
|
||||
return `${this.basePath}/download/${tag}/${fileName}`;
|
||||
}
|
||||
}
|
||||
|
||||
export interface CustomGitHubOptions {
|
||||
channel: string;
|
||||
repo: string;
|
||||
owner: string;
|
||||
releaseType: 'release' | 'prerelease';
|
||||
}
|
||||
|
||||
function getNoteValue(parent: XElement): string {
|
||||
const result = parent.elementValueOrEmpty('content');
|
||||
// GitHub reports empty notes as <content>No content.</content>
|
||||
return result === 'No content.' ? '' : result;
|
||||
}
|
||||
|
||||
export function computeReleaseNotes(
|
||||
currentVersion: semver.SemVer,
|
||||
isFullChangelog: boolean,
|
||||
feed: XElement,
|
||||
latestRelease: any
|
||||
): string | Array<ReleaseNoteInfo> | null {
|
||||
if (!isFullChangelog) {
|
||||
return getNoteValue(latestRelease);
|
||||
}
|
||||
|
||||
const releaseNotes: Array<ReleaseNoteInfo> = [];
|
||||
for (const release of feed.getElements('entry')) {
|
||||
// noinspection TypeScriptValidateJSTypes
|
||||
const versionRelease = /\/tag\/v?([^/]+)$/.exec(
|
||||
release.element('link').attribute('href')
|
||||
)?.[1];
|
||||
if (versionRelease && semver.lt(currentVersion, versionRelease)) {
|
||||
releaseNotes.push({
|
||||
version: versionRelease,
|
||||
note: getNoteValue(release),
|
||||
});
|
||||
}
|
||||
}
|
||||
return releaseNotes.sort((a, b) => semver.rcompare(a.version, b.version));
|
||||
}
|
||||
|
||||
// addRandomQueryToAvoidCaching is false by default because in most cases URL already contains version number,
|
||||
// so, it makes sense only for Generic Provider for channel files
|
||||
function newUrlFromBase(
|
||||
pathname: string,
|
||||
baseUrl: URL,
|
||||
addRandomQueryToAvoidCaching = false
|
||||
): URL {
|
||||
const result = new URL(pathname, baseUrl);
|
||||
// search is not propagated (search is an empty string if not specified)
|
||||
const search = baseUrl.search;
|
||||
if (search != null && search.length !== 0) {
|
||||
result.search = search;
|
||||
} else if (addRandomQueryToAvoidCaching) {
|
||||
result.search = `noCache=${Date.now().toString(32)}`;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getChannelFilename(channel: string): string {
|
||||
return `${channel}.yml`;
|
||||
}
|
||||
@@ -2,8 +2,9 @@ import { app } from 'electron';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { isMacOS } from '../../shared/utils';
|
||||
import { isMacOS, isWindows } from '../../shared/utils';
|
||||
import { logger } from '../logger';
|
||||
import { CustomGitHubProvider } from './custom-github-provider';
|
||||
import { updaterSubjects } from './event';
|
||||
|
||||
export const ReleaseTypeSchema = z.enum([
|
||||
@@ -36,12 +37,12 @@ export const checkForUpdates = async (force = true) => {
|
||||
|
||||
export const registerUpdater = async () => {
|
||||
// skip auto update in dev mode & internal
|
||||
if (isDev || buildType === 'internal') {
|
||||
if (buildType === 'internal') {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: support auto update on windows and linux
|
||||
const allowAutoUpdate = isMacOS();
|
||||
// TODO: support auto update on linux
|
||||
const allowAutoUpdate = isMacOS() || isWindows();
|
||||
|
||||
autoUpdater.logger = logger;
|
||||
autoUpdater.autoDownload = false;
|
||||
@@ -51,11 +52,14 @@ export const registerUpdater = async () => {
|
||||
|
||||
const feedUrl: Parameters<typeof autoUpdater.setFeedURL>[0] = {
|
||||
channel: buildType,
|
||||
provider: 'github',
|
||||
// hack for custom provider
|
||||
provider: 'custom' as 'github',
|
||||
// @ts-expect-error - just ignore for now
|
||||
repo: buildType !== 'internal' ? 'AFFiNE' : 'AFFiNE-Releases',
|
||||
owner: 'toeverything',
|
||||
releaseType: buildType === 'stable' ? 'release' : 'prerelease',
|
||||
// @ts-expect-error hack for custom provider
|
||||
updateProvider: CustomGitHubProvider,
|
||||
};
|
||||
|
||||
logger.debug('auto-updater feed config', feedUrl);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/prototype",
|
||||
"private": true,
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host --port 3003",
|
||||
@@ -18,13 +18,13 @@
|
||||
"@affine/jotai": "workspace:*",
|
||||
"@affine/templates": "workspace:*",
|
||||
"@affine/workspace": "workspace:*",
|
||||
"@blocksuite/block-std": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/block-std": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/icons": "^2.1.31",
|
||||
"@blocksuite/lit": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@toeverything/hooks": "workspace:*",
|
||||
"@toeverything/y-indexeddb": "workspace:*",
|
||||
"react": "^18.2.0",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/server",
|
||||
"private": true,
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"description": "Affine Node.js server",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
"wait-on": "^7.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/block-std": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/block-std": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/icons": "^2.1.31",
|
||||
"@blocksuite/lit": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"chromatic": "^6.22.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
@@ -52,5 +52,5 @@
|
||||
"@blocksuite/lit": "*",
|
||||
"@blocksuite/store": "*"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -105,3 +105,23 @@ WorkspaceList.parameters = {
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export const SearchPage: StoryFn = () => {
|
||||
return <FakeApp />;
|
||||
};
|
||||
SearchPage.play = async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
await waitFor(async () => {
|
||||
assertExists(canvasElement.querySelector('v-line'));
|
||||
});
|
||||
await userEvent.click(canvas.getByTestId('slider-bar-quick-search-button'));
|
||||
};
|
||||
SearchPage.decorators = [withRouter];
|
||||
SearchPage.parameters = {
|
||||
reactRouter: reactRouterParameters({
|
||||
routing: reactRouterOutlets(routes),
|
||||
location: {
|
||||
path: '/',
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ImagePreviewModal } from '@affine/image-preview-plugin/src/component';
|
||||
import { rootBlockHubAtom } from '@affine/workspace/atom';
|
||||
import { getOrCreateWorkspace } from '@affine/workspace/manager';
|
||||
import type { Meta } from '@storybook/react';
|
||||
import { useCallback } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
export default {
|
||||
@@ -53,7 +54,11 @@ export const Default = () => {
|
||||
overflow: 'auto',
|
||||
}}
|
||||
>
|
||||
<BlockSuiteEditor mode="page" page={page} onInit={initEmptyPage} />
|
||||
<BlockSuiteEditor
|
||||
mode="page"
|
||||
page={page}
|
||||
onInit={useCallback(async page => initEmptyPage(page), [])}
|
||||
/>
|
||||
{createPortal(
|
||||
<ImagePreviewModal pageId={page.id} workspace={page.workspace} />,
|
||||
document.body
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/monorepo",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"private": true,
|
||||
"author": "toeverything",
|
||||
"license": "MPL-2.0",
|
||||
|
||||
2
packages/@types/env/package.json
vendored
2
packages/@types/env/package.json
vendored
@@ -7,5 +7,5 @@
|
||||
"@affine/env": "workspace:*",
|
||||
"@toeverything/infra": "workspace:*"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
"peerDependencies": {
|
||||
"ts-node": "*"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -51,12 +51,12 @@
|
||||
"rxjs": "^7.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/icons": "^2.1.31",
|
||||
"@blocksuite/lit": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@types/react": "^18.2.20",
|
||||
"@types/react-datepicker": "^4.15.0",
|
||||
"@types/react-dnd": "^3.0.2",
|
||||
@@ -66,5 +66,5 @@
|
||||
"vite": "^4.4.9",
|
||||
"yjs": "^13.6.7"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export const variableDefineMap = {
|
||||
icon: <FavoriteIcon />,
|
||||
},
|
||||
Tags: {
|
||||
type: meta => tArray(tTag.create({ tags: meta.tags.options })),
|
||||
type: meta => tArray(tTag.create({ tags: meta.tags?.options ?? [] })),
|
||||
icon: <TagsIcon />,
|
||||
},
|
||||
// Imported: {
|
||||
|
||||
@@ -97,6 +97,28 @@ export const mainContainerStyle = style({
|
||||
},
|
||||
} as ComplexStyleRule);
|
||||
|
||||
// These styles override the default styles of the react-resizable-panels
|
||||
// as the default styles make the overflow part hidden when printing to PDF.
|
||||
// See https://github.com/toeverything/AFFiNE/pull/3893
|
||||
globalStyle(`${mainContainerStyle} > div[data-panel-group]`, {
|
||||
'@media': {
|
||||
print: {
|
||||
overflow: 'visible !important',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// These styles override the default styles of the react-resizable-panels
|
||||
// as the default styles make the overflow part hidden when printing to PDF.
|
||||
// See https://github.com/toeverything/AFFiNE/pull/3893
|
||||
globalStyle(`${mainContainerStyle} > div[data-panel-group] > div[data-panel]`, {
|
||||
'@media': {
|
||||
print: {
|
||||
overflow: 'visible !important',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const toolStyle = style({
|
||||
position: 'fixed',
|
||||
right: '30px',
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"devDependencies": {
|
||||
"@types/debug": "^4.1.8"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
4
packages/env/package.json
vendored
4
packages/env/package.json
vendored
@@ -5,7 +5,7 @@
|
||||
"main": "./src/index.ts",
|
||||
"module": "./src/index.ts",
|
||||
"devDependencies": {
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"zod": "^3.22.1"
|
||||
@@ -27,5 +27,5 @@
|
||||
"dependencies": {
|
||||
"lit": "^2.8.0"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { dirname, resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
import type { Array as YArray, Map as YMap } from 'yjs';
|
||||
import { applyUpdate, Doc } from 'yjs';
|
||||
|
||||
import { migrateToSubdoc } from '../blocksuite/index.js';
|
||||
|
||||
const fixturePath = resolve(
|
||||
dirname(fileURLToPath(import.meta.url)),
|
||||
'workspace.ydoc'
|
||||
);
|
||||
const yDocBuffer = readFileSync(fixturePath);
|
||||
const doc = new Doc();
|
||||
applyUpdate(doc, new Uint8Array(yDocBuffer));
|
||||
const migratedDoc = migrateToSubdoc(doc);
|
||||
|
||||
describe('subdoc', () => {
|
||||
test('Migration to subdoc', async () => {
|
||||
const { default: json } = await import('@affine-test/fixtures/output.json');
|
||||
const length = Object.keys(json).length;
|
||||
const binary = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
binary[i] = (json as any)[i];
|
||||
}
|
||||
const doc = new Doc();
|
||||
applyUpdate(doc, binary);
|
||||
{
|
||||
// invoke data
|
||||
doc.getMap('space:hello-world');
|
||||
doc.getMap('space:meta');
|
||||
}
|
||||
const blocks = doc.getMap('space:hello-world').toJSON();
|
||||
const newDoc = migrateToSubdoc(doc);
|
||||
const subDoc = newDoc.getMap('spaces').get('space:hello-world') as Doc;
|
||||
const data = (subDoc.toJSON() as any).blocks;
|
||||
Object.keys(data).forEach(id => {
|
||||
if (id === 'xyWNqindHH') {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
blocks[id]['sys:flavour'] === 'affine:surface' &&
|
||||
!blocks[id]['prop:elements']
|
||||
) {
|
||||
blocks[id]['prop:elements'] = data[id]['prop:elements'];
|
||||
}
|
||||
expect(data[id]).toEqual(blocks[id]);
|
||||
});
|
||||
});
|
||||
|
||||
test('Test fixture should be set correctly', () => {
|
||||
const meta = doc.getMap('space:meta');
|
||||
const versions = meta.get('versions') as YMap<unknown>;
|
||||
expect(versions.get('affine:code')).toBeTypeOf('number');
|
||||
});
|
||||
|
||||
test('Meta data should be migrated correctly', () => {
|
||||
const originalMeta = doc.getMap('space:meta');
|
||||
const originalVersions = originalMeta.get('versions') as YMap<unknown>;
|
||||
|
||||
const meta = migratedDoc.getMap('meta');
|
||||
const blockVersions = meta.get('blockVersions') as YMap<unknown>;
|
||||
|
||||
expect(meta.get('workspaceVersion')).toBe(1);
|
||||
expect(blockVersions.get('affine:code')).toBe(
|
||||
originalVersions.get('affine:code')
|
||||
);
|
||||
expect((meta.get('pages') as YArray<unknown>).length).toBe(
|
||||
(originalMeta.get('pages') as YArray<unknown>).length
|
||||
);
|
||||
|
||||
expect(blockVersions.get('affine:embed')).toBeUndefined();
|
||||
expect(blockVersions.get('affine:image')).toBe(
|
||||
originalVersions.get('affine:embed')
|
||||
);
|
||||
|
||||
expect(blockVersions.get('affine:frame')).toBeUndefined();
|
||||
expect(blockVersions.get('affine:note')).toBe(
|
||||
originalVersions.get('affine:frame')
|
||||
);
|
||||
});
|
||||
});
|
||||
BIN
packages/env/src/__tests__/workspace.ydoc
vendored
BIN
packages/env/src/__tests__/workspace.ydoc
vendored
Binary file not shown.
6
packages/env/src/blocksuite/index.ts
vendored
6
packages/env/src/blocksuite/index.ts
vendored
@@ -3,14 +3,12 @@ import type { Page } from '@blocksuite/store';
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export async function initEmptyPage(page: Page) {
|
||||
export async function initEmptyPage(page: Page, title?: string) {
|
||||
await page.waitForLoaded();
|
||||
const pageBlockId = page.addBlock('affine:page', {
|
||||
title: new page.Text(''),
|
||||
title: new page.Text(title || ''),
|
||||
});
|
||||
page.addBlock('affine:surface', {}, pageBlockId);
|
||||
const noteBlockId = page.addBlock('affine:note', {}, pageBlockId);
|
||||
page.addBlock('affine:paragraph', {}, noteBlockId);
|
||||
}
|
||||
|
||||
export * from './subdoc-migration.js';
|
||||
|
||||
267
packages/env/src/blocksuite/subdoc-migration.ts
vendored
267
packages/env/src/blocksuite/subdoc-migration.ts
vendored
@@ -1,267 +0,0 @@
|
||||
import type { Schema } from '@blocksuite/store';
|
||||
import { Array as YArray, Doc as YDoc, Map as YMap } from 'yjs';
|
||||
|
||||
type XYWH = [number, number, number, number];
|
||||
|
||||
function deserializeXYWH(xywh: string): XYWH {
|
||||
return JSON.parse(xywh) as XYWH;
|
||||
}
|
||||
|
||||
function migrateDatabase(data: YMap<unknown>) {
|
||||
data.delete('prop:mode');
|
||||
data.set('prop:views', new YArray());
|
||||
const columns = (data.get('prop:columns') as YArray<unknown>).toJSON() as {
|
||||
id: string;
|
||||
name: string;
|
||||
hide: boolean;
|
||||
type: string;
|
||||
width: number;
|
||||
selection?: unknown[];
|
||||
}[];
|
||||
const views = [
|
||||
{
|
||||
id: 'default',
|
||||
name: 'Table',
|
||||
columns: columns.map(col => ({
|
||||
id: col.id,
|
||||
width: col.width,
|
||||
hide: col.hide,
|
||||
})),
|
||||
filter: { type: 'group', op: 'and', conditions: [] },
|
||||
mode: 'table',
|
||||
},
|
||||
];
|
||||
const cells = (data.get('prop:cells') as YMap<unknown>).toJSON() as Record<
|
||||
string,
|
||||
Record<
|
||||
string,
|
||||
{
|
||||
id: string;
|
||||
value: unknown;
|
||||
}
|
||||
>
|
||||
>;
|
||||
const convertColumn = (
|
||||
id: string,
|
||||
update: (cell: { id: string; value: unknown }) => void
|
||||
) => {
|
||||
Object.values(cells).forEach(row => {
|
||||
if (row[id] != null) {
|
||||
update(row[id]);
|
||||
}
|
||||
});
|
||||
};
|
||||
const newColumns = columns.map(v => {
|
||||
let data: Record<string, unknown> = {};
|
||||
if (v.type === 'select' || v.type === 'multi-select') {
|
||||
data = { options: v.selection };
|
||||
if (v.type === 'select') {
|
||||
convertColumn(v.id, cell => {
|
||||
if (Array.isArray(cell.value)) {
|
||||
cell.value = cell.value[0]?.id;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
convertColumn(v.id, cell => {
|
||||
if (Array.isArray(cell.value)) {
|
||||
cell.value = cell.value.map(v => v.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (v.type === 'number') {
|
||||
convertColumn(v.id, cell => {
|
||||
if (typeof cell.value === 'string') {
|
||||
cell.value = Number.parseFloat(cell.value.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
id: v.id,
|
||||
type: v.type,
|
||||
name: v.name,
|
||||
data,
|
||||
};
|
||||
});
|
||||
data.set('prop:columns', newColumns);
|
||||
data.set('prop:views', views);
|
||||
data.set('prop:cells', cells);
|
||||
}
|
||||
|
||||
function runBlockMigration(
|
||||
flavour: string,
|
||||
data: YMap<unknown>,
|
||||
version: number
|
||||
) {
|
||||
if (flavour === 'affine:frame') {
|
||||
data.set('sys:flavour', 'affine:note');
|
||||
return;
|
||||
}
|
||||
if (flavour === 'affine:surface' && version <= 3) {
|
||||
if (data.has('elements')) {
|
||||
const elements = data.get('elements') as YMap<unknown>;
|
||||
migrateSurface(elements);
|
||||
data.set('prop:elements', elements.clone());
|
||||
data.delete('elements');
|
||||
} else {
|
||||
data.set('prop:elements', new YMap());
|
||||
}
|
||||
}
|
||||
if (flavour === 'affine:embed') {
|
||||
data.set('sys:flavour', 'affine:image');
|
||||
data.delete('prop:type');
|
||||
}
|
||||
if (flavour === 'affine:database' && version < 2) {
|
||||
migrateDatabase(data);
|
||||
}
|
||||
}
|
||||
|
||||
function migrateSurface(data: YMap<unknown>) {
|
||||
for (const [, value] of <IterableIterator<[string, YMap<unknown>]>>(
|
||||
data.entries()
|
||||
)) {
|
||||
if (value.get('type') === 'connector') {
|
||||
migrateSurfaceConnector(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function migrateSurfaceConnector(data: YMap<any>) {
|
||||
let id = data.get('startElement')?.id;
|
||||
const controllers = data.get('controllers');
|
||||
const length = controllers.length;
|
||||
const xywh = deserializeXYWH(data.get('xywh'));
|
||||
if (id) {
|
||||
data.set('source', { id });
|
||||
} else {
|
||||
data.set('source', {
|
||||
position: [controllers[0].x + xywh[0], controllers[0].y + xywh[1]],
|
||||
});
|
||||
}
|
||||
|
||||
id = data.get('endElement')?.id;
|
||||
if (id) {
|
||||
data.set('target', { id });
|
||||
} else {
|
||||
data.set('target', {
|
||||
position: [
|
||||
controllers[length - 1].x + xywh[0],
|
||||
controllers[length - 1].y + xywh[1],
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const width = data.get('lineWidth') ?? 4;
|
||||
data.set('strokeWidth', width);
|
||||
const color = data.get('color');
|
||||
data.set('stroke', color);
|
||||
|
||||
data.delete('startElement');
|
||||
data.delete('endElement');
|
||||
data.delete('controllers');
|
||||
data.delete('lineWidth');
|
||||
data.delete('color');
|
||||
data.delete('xywh');
|
||||
}
|
||||
|
||||
function updateBlockVersions(versions: YMap<number>) {
|
||||
const frameVersion = versions.get('affine:frame');
|
||||
if (frameVersion !== undefined) {
|
||||
versions.set('affine:note', frameVersion);
|
||||
versions.delete('affine:frame');
|
||||
}
|
||||
const embedVersion = versions.get('affine:embed');
|
||||
if (embedVersion !== undefined) {
|
||||
versions.set('affine:image', embedVersion);
|
||||
versions.delete('affine:embed');
|
||||
}
|
||||
const databaseVersion = versions.get('affine:database');
|
||||
if (databaseVersion !== undefined && databaseVersion < 2) {
|
||||
versions.set('affine:database', 2);
|
||||
}
|
||||
}
|
||||
|
||||
function migrateMeta(oldDoc: YDoc, newDoc: YDoc) {
|
||||
const originalMeta = oldDoc.getMap('space:meta');
|
||||
const originalVersions = originalMeta.get('versions') as YMap<number>;
|
||||
const originalPages = originalMeta.get('pages') as YArray<YMap<unknown>>;
|
||||
const meta = newDoc.getMap('meta');
|
||||
const pages = new YArray();
|
||||
const blockVersions = originalVersions.clone();
|
||||
|
||||
meta.set('workspaceVersion', 1);
|
||||
meta.set('blockVersions', blockVersions);
|
||||
meta.set('pages', pages);
|
||||
meta.set('name', originalMeta.get('name') as string);
|
||||
|
||||
updateBlockVersions(blockVersions);
|
||||
const mapList = originalPages.map(page => {
|
||||
const map = new YMap();
|
||||
Array.from(page.entries())
|
||||
.filter(([key]) => key !== 'subpageIds')
|
||||
.forEach(([key, value]) => {
|
||||
map.set(key, value);
|
||||
});
|
||||
return map;
|
||||
});
|
||||
pages.push(mapList);
|
||||
}
|
||||
|
||||
function migrateBlocks(oldDoc: YDoc, newDoc: YDoc) {
|
||||
const spaces = newDoc.getMap('spaces');
|
||||
const originalMeta = oldDoc.getMap('space:meta');
|
||||
const originalVersions = originalMeta.get('versions') as YMap<number>;
|
||||
const originalPages = originalMeta.get('pages') as YArray<YMap<unknown>>;
|
||||
originalPages.forEach(page => {
|
||||
const id = page.get('id') as string;
|
||||
const spaceId = id.startsWith('space:') ? id : `space:${id}`;
|
||||
const originalBlocks = oldDoc.getMap(spaceId) as YMap<unknown>;
|
||||
const subdoc = new YDoc();
|
||||
spaces.set(spaceId, subdoc);
|
||||
const blocks = subdoc.getMap('blocks');
|
||||
Array.from(originalBlocks.entries()).forEach(([key, value]) => {
|
||||
const blockData = value.clone();
|
||||
blocks.set(key, blockData);
|
||||
const flavour = blockData.get('sys:flavour') as string;
|
||||
const version = originalVersions.get(flavour);
|
||||
if (version !== undefined) {
|
||||
runBlockMigration(flavour, blockData, version);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function migrateToSubdoc(doc: YDoc): YDoc {
|
||||
const needMigration = Array.from(doc.getMap('space:meta').keys()).length > 0;
|
||||
if (!needMigration) {
|
||||
return doc;
|
||||
}
|
||||
const output = new YDoc();
|
||||
migrateMeta(doc, output);
|
||||
migrateBlocks(doc, output);
|
||||
return output;
|
||||
}
|
||||
|
||||
export async function migrateDatabaseBlockTo3(rootDoc: YDoc, schema: Schema) {
|
||||
const spaces = rootDoc.getMap('spaces') as YMap<any>;
|
||||
spaces.forEach(space => {
|
||||
schema.upgradePage(
|
||||
{
|
||||
'affine:note': 1,
|
||||
'affine:bookmark': 1,
|
||||
'affine:database': 2,
|
||||
'affine:divider': 1,
|
||||
'affine:image': 1,
|
||||
'affine:list': 1,
|
||||
'affine:code': 1,
|
||||
'affine:page': 2,
|
||||
'affine:paragraph': 1,
|
||||
'affine:surface': 3,
|
||||
},
|
||||
space
|
||||
);
|
||||
});
|
||||
const meta = rootDoc.getMap('meta') as YMap<unknown>;
|
||||
const versions = meta.get('blockVersions') as YMap<number>;
|
||||
versions.set('affine:database', 3);
|
||||
}
|
||||
5
packages/env/src/workspace.ts
vendored
5
packages/env/src/workspace.ts
vendored
@@ -10,11 +10,6 @@ import type { PropsWithChildren, ReactNode } from 'react';
|
||||
|
||||
import type { Collection } from './filter.js';
|
||||
|
||||
export enum WorkspaceVersion {
|
||||
SubDoc = 2,
|
||||
DatabaseV3 = 3,
|
||||
}
|
||||
|
||||
export enum WorkspaceSubPath {
|
||||
ALL = 'all',
|
||||
SETTING = 'setting',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/graphql",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"description": "Autogenerated GraphQL client for affine.pro",
|
||||
"license": "MPL-2.0",
|
||||
"type": "module",
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
"devDependencies": {
|
||||
"@affine/env": "workspace:*",
|
||||
"@affine/y-provider": "workspace:*",
|
||||
"@blocksuite/block-std": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/block-std": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@affine/y-provider": "workspace:*",
|
||||
@@ -53,5 +53,5 @@
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -37,5 +37,5 @@
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -317,6 +317,7 @@
|
||||
"Zoom to 100%": "Zoom to 100%",
|
||||
"Zoom to fit": "Zoom to fit",
|
||||
"all": "all",
|
||||
"com.affine.loading": "Loading...",
|
||||
"com.affine.banner.content": "This demo is limited. <1>Download the AFFiNE Client</1> for the latest features and Performance.",
|
||||
"com.affine.cloudTempDisable.description": "We are upgrading the AFFiNE Cloud service and it is temporarily unavailable on the client side. If you wish to stay updated on the progress and be notified on availability, you can fill out the <1>AFFiNE Cloud Signup</1>.",
|
||||
"com.affine.cloudTempDisable.title": "AFFiNE Cloud is upgrading now.",
|
||||
|
||||
@@ -50,20 +50,21 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@affine/sdk": "workspace:*",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"jotai": "^2.3.1",
|
||||
"zod": "^3.22.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/editor": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"async-call-rpc": "^6.3.1",
|
||||
"electron": "link:../../apps/electron/node_modules/electron",
|
||||
"react": "^18.2.0",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-dts": "3.5.2"
|
||||
"vite-plugin-dts": "3.5.2",
|
||||
"yjs": "^13.6.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@affine/templates": "*",
|
||||
@@ -71,7 +72,8 @@
|
||||
"@blocksuite/lit": "*",
|
||||
"async-call-rpc": "*",
|
||||
"electron": "*",
|
||||
"react": "*"
|
||||
"react": "*",
|
||||
"yjs": "^13"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@affine/templates": {
|
||||
@@ -91,7 +93,10 @@
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"yjs": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { PageMeta, Workspace } from '@blocksuite/store';
|
||||
import { createIndexeddbStorage } from '@blocksuite/store';
|
||||
import type { createStore, WritableAtom } from 'jotai/vanilla';
|
||||
import { Array as YArray, Doc as YDoc, Map as YMap } from 'yjs';
|
||||
|
||||
export async function buildShowcaseWorkspace(
|
||||
workspace: Workspace,
|
||||
@@ -26,7 +28,9 @@ export async function buildShowcaseWorkspace(
|
||||
'affine:bookmark': 1,
|
||||
'affine:database': 2,
|
||||
};
|
||||
workspace.doc.getMap('meta').set('blockVersions', showcaseWorkspaceVersions);
|
||||
workspace.doc
|
||||
.getMap('meta')
|
||||
.set('blockVersions', new YMap(Object.entries(showcaseWorkspaceVersions)));
|
||||
const prototypes = {
|
||||
tags: {
|
||||
options: [
|
||||
@@ -188,3 +192,380 @@ export async function buildShowcaseWorkspace(
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
import { applyUpdate, encodeStateAsUpdate } from 'yjs';
|
||||
|
||||
const migrationOrigin = 'affine-migration';
|
||||
|
||||
import type { Schema } from '@blocksuite/store';
|
||||
|
||||
type XYWH = [number, number, number, number];
|
||||
|
||||
function deserializeXYWH(xywh: string): XYWH {
|
||||
return JSON.parse(xywh) as XYWH;
|
||||
}
|
||||
|
||||
function migrateDatabase(data: YMap<unknown>) {
|
||||
data.delete('prop:mode');
|
||||
data.set('prop:views', new YArray());
|
||||
const columns = (data.get('prop:columns') as YArray<unknown>).toJSON() as {
|
||||
id: string;
|
||||
name: string;
|
||||
hide: boolean;
|
||||
type: string;
|
||||
width: number;
|
||||
selection?: unknown[];
|
||||
}[];
|
||||
const views = [
|
||||
{
|
||||
id: 'default',
|
||||
name: 'Table',
|
||||
columns: columns.map(col => ({
|
||||
id: col.id,
|
||||
width: col.width,
|
||||
hide: col.hide,
|
||||
})),
|
||||
filter: { type: 'group', op: 'and', conditions: [] },
|
||||
mode: 'table',
|
||||
},
|
||||
];
|
||||
const cells = (data.get('prop:cells') as YMap<unknown>).toJSON() as Record<
|
||||
string,
|
||||
Record<
|
||||
string,
|
||||
{
|
||||
id: string;
|
||||
value: unknown;
|
||||
}
|
||||
>
|
||||
>;
|
||||
const convertColumn = (
|
||||
id: string,
|
||||
update: (cell: { id: string; value: unknown }) => void
|
||||
) => {
|
||||
Object.values(cells).forEach(row => {
|
||||
if (row[id] != null) {
|
||||
update(row[id]);
|
||||
}
|
||||
});
|
||||
};
|
||||
const newColumns = columns.map(v => {
|
||||
let data: Record<string, unknown> = {};
|
||||
if (v.type === 'select' || v.type === 'multi-select') {
|
||||
data = { options: v.selection };
|
||||
if (v.type === 'select') {
|
||||
convertColumn(v.id, cell => {
|
||||
if (Array.isArray(cell.value)) {
|
||||
cell.value = cell.value[0]?.id;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
convertColumn(v.id, cell => {
|
||||
if (Array.isArray(cell.value)) {
|
||||
cell.value = cell.value.map(v => v.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (v.type === 'number') {
|
||||
convertColumn(v.id, cell => {
|
||||
if (typeof cell.value === 'string') {
|
||||
cell.value = Number.parseFloat(cell.value.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
id: v.id,
|
||||
type: v.type,
|
||||
name: v.name,
|
||||
data,
|
||||
};
|
||||
});
|
||||
data.set('prop:columns', newColumns);
|
||||
data.set('prop:views', views);
|
||||
data.set('prop:cells', cells);
|
||||
}
|
||||
|
||||
function runBlockMigration(
|
||||
flavour: string,
|
||||
data: YMap<unknown>,
|
||||
version: number
|
||||
) {
|
||||
if (flavour === 'affine:frame') {
|
||||
data.set('sys:flavour', 'affine:note');
|
||||
return;
|
||||
}
|
||||
if (flavour === 'affine:surface' && version <= 3) {
|
||||
if (data.has('elements')) {
|
||||
const elements = data.get('elements') as YMap<unknown>;
|
||||
migrateSurface(elements);
|
||||
data.set('prop:elements', elements.clone());
|
||||
data.delete('elements');
|
||||
} else {
|
||||
data.set('prop:elements', new YMap());
|
||||
}
|
||||
}
|
||||
if (flavour === 'affine:embed') {
|
||||
data.set('sys:flavour', 'affine:image');
|
||||
data.delete('prop:type');
|
||||
}
|
||||
if (flavour === 'affine:database' && version < 2) {
|
||||
migrateDatabase(data);
|
||||
}
|
||||
}
|
||||
|
||||
function migrateSurface(data: YMap<unknown>) {
|
||||
for (const [, value] of <IterableIterator<[string, YMap<unknown>]>>(
|
||||
data.entries()
|
||||
)) {
|
||||
if (value.get('type') === 'connector') {
|
||||
migrateSurfaceConnector(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function migrateSurfaceConnector(data: YMap<any>) {
|
||||
let id = data.get('startElement')?.id;
|
||||
const controllers = data.get('controllers');
|
||||
const length = controllers.length;
|
||||
const xywh = deserializeXYWH(data.get('xywh'));
|
||||
if (id) {
|
||||
data.set('source', { id });
|
||||
} else {
|
||||
data.set('source', {
|
||||
position: [controllers[0].x + xywh[0], controllers[0].y + xywh[1]],
|
||||
});
|
||||
}
|
||||
|
||||
id = data.get('endElement')?.id;
|
||||
if (id) {
|
||||
data.set('target', { id });
|
||||
} else {
|
||||
data.set('target', {
|
||||
position: [
|
||||
controllers[length - 1].x + xywh[0],
|
||||
controllers[length - 1].y + xywh[1],
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const width = data.get('lineWidth') ?? 4;
|
||||
data.set('strokeWidth', width);
|
||||
const color = data.get('color');
|
||||
data.set('stroke', color);
|
||||
|
||||
data.delete('startElement');
|
||||
data.delete('endElement');
|
||||
data.delete('controllers');
|
||||
data.delete('lineWidth');
|
||||
data.delete('color');
|
||||
data.delete('xywh');
|
||||
}
|
||||
|
||||
function updateBlockVersions(versions: YMap<number>) {
|
||||
const frameVersion = versions.get('affine:frame');
|
||||
if (frameVersion !== undefined) {
|
||||
versions.set('affine:note', frameVersion);
|
||||
versions.delete('affine:frame');
|
||||
}
|
||||
const embedVersion = versions.get('affine:embed');
|
||||
if (embedVersion !== undefined) {
|
||||
versions.set('affine:image', embedVersion);
|
||||
versions.delete('affine:embed');
|
||||
}
|
||||
const databaseVersion = versions.get('affine:database');
|
||||
if (databaseVersion !== undefined && databaseVersion < 2) {
|
||||
versions.set('affine:database', 2);
|
||||
}
|
||||
}
|
||||
|
||||
function migrateMeta(oldDoc: YDoc, newDoc: YDoc) {
|
||||
const originalMeta = oldDoc.getMap('space:meta');
|
||||
const originalVersions = originalMeta.get('versions') as YMap<number>;
|
||||
const originalPages = originalMeta.get('pages') as YArray<YMap<unknown>>;
|
||||
const meta = newDoc.getMap('meta');
|
||||
const pages = new YArray();
|
||||
const blockVersions = originalVersions.clone();
|
||||
|
||||
meta.set('workspaceVersion', 1);
|
||||
meta.set('blockVersions', blockVersions);
|
||||
meta.set('pages', pages);
|
||||
meta.set('name', originalMeta.get('name') as string);
|
||||
|
||||
updateBlockVersions(blockVersions);
|
||||
const mapList = originalPages.map(page => {
|
||||
const map = new YMap();
|
||||
Array.from(page.entries())
|
||||
.filter(([key]) => key !== 'subpageIds')
|
||||
.forEach(([key, value]) => {
|
||||
map.set(key, value);
|
||||
});
|
||||
return map;
|
||||
});
|
||||
pages.push(mapList);
|
||||
}
|
||||
|
||||
function migrateBlocks(oldDoc: YDoc, newDoc: YDoc) {
|
||||
const spaces = newDoc.getMap('spaces');
|
||||
const originalMeta = oldDoc.getMap('space:meta');
|
||||
const originalVersions = originalMeta.get('versions') as YMap<number>;
|
||||
const originalPages = originalMeta.get('pages') as YArray<YMap<unknown>>;
|
||||
originalPages.forEach(page => {
|
||||
const id = page.get('id') as string;
|
||||
const spaceId = id.startsWith('space:') ? id : `space:${id}`;
|
||||
const originalBlocks = oldDoc.getMap(spaceId) as YMap<unknown>;
|
||||
const subdoc = new YDoc();
|
||||
spaces.set(spaceId, subdoc);
|
||||
const blocks = subdoc.getMap('blocks');
|
||||
Array.from(originalBlocks.entries()).forEach(([key, value]) => {
|
||||
const blockData = value.clone();
|
||||
blocks.set(key, blockData);
|
||||
const flavour = blockData.get('sys:flavour') as string;
|
||||
const version = originalVersions.get(flavour);
|
||||
if (version !== undefined) {
|
||||
runBlockMigration(flavour, blockData, version);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function migrateToSubdoc(oldDoc: YDoc): YDoc {
|
||||
const needMigration =
|
||||
Array.from(oldDoc.getMap('space:meta').keys()).length > 0;
|
||||
if (!needMigration) {
|
||||
return oldDoc;
|
||||
}
|
||||
const newDoc = new YDoc();
|
||||
migrateMeta(oldDoc, newDoc);
|
||||
migrateBlocks(oldDoc, newDoc);
|
||||
return newDoc;
|
||||
}
|
||||
|
||||
export async function migrateDatabaseBlockTo3(rootDoc: YDoc, schema: Schema) {
|
||||
const spaces = rootDoc.getMap('spaces') as YMap<any>;
|
||||
spaces.forEach(space => {
|
||||
schema.upgradePage(
|
||||
{
|
||||
'affine:note': 1,
|
||||
'affine:bookmark': 1,
|
||||
'affine:database': 2,
|
||||
'affine:divider': 1,
|
||||
'affine:image': 1,
|
||||
'affine:list': 1,
|
||||
'affine:code': 1,
|
||||
'affine:page': 2,
|
||||
'affine:paragraph': 1,
|
||||
'affine:surface': 3,
|
||||
},
|
||||
space
|
||||
);
|
||||
});
|
||||
const meta = rootDoc.getMap('meta') as YMap<unknown>;
|
||||
const versions = meta.get('blockVersions') as YMap<number>;
|
||||
versions.set('affine:database', 3);
|
||||
}
|
||||
|
||||
export type UpgradeOptions = {
|
||||
getCurrentRootDoc: () => Promise<YDoc>;
|
||||
createWorkspace: () => Promise<Workspace>;
|
||||
getSchema: () => Schema;
|
||||
};
|
||||
|
||||
const upgradeV1ToV2 = async (options: UpgradeOptions) => {
|
||||
const oldDoc = await options.getCurrentRootDoc();
|
||||
const newDoc = migrateToSubdoc(oldDoc);
|
||||
const newWorkspace = await options.createWorkspace();
|
||||
applyUpdate(newWorkspace.doc, encodeStateAsUpdate(newDoc), migrationOrigin);
|
||||
newDoc.getSubdocs().forEach(subdoc => {
|
||||
newWorkspace.doc.getSubdocs().forEach(newDoc => {
|
||||
if (subdoc.guid === newDoc.guid) {
|
||||
applyUpdate(newDoc, encodeStateAsUpdate(subdoc), migrationOrigin);
|
||||
}
|
||||
});
|
||||
});
|
||||
return newWorkspace;
|
||||
};
|
||||
|
||||
const upgradeV2ToV3 = async (options: UpgradeOptions): Promise<boolean> => {
|
||||
const rootDoc = await options.getCurrentRootDoc();
|
||||
const spaces = rootDoc.getMap('spaces') as YMap<any>;
|
||||
const meta = rootDoc.getMap('meta') as YMap<unknown>;
|
||||
const versions = meta.get('blockVersions') as YMap<number>;
|
||||
if ('affine:database' in versions) {
|
||||
if (versions['affine:database'] === 3) {
|
||||
return false;
|
||||
}
|
||||
} else if (versions.get('affine:database') === 3) {
|
||||
return false;
|
||||
}
|
||||
const schema = options.getSchema();
|
||||
spaces.forEach(space => {
|
||||
schema.upgradePage(
|
||||
{
|
||||
'affine:note': 1,
|
||||
'affine:bookmark': 1,
|
||||
'affine:database': 2,
|
||||
'affine:divider': 1,
|
||||
'affine:image': 1,
|
||||
'affine:list': 1,
|
||||
'affine:code': 1,
|
||||
'affine:page': 2,
|
||||
'affine:paragraph': 1,
|
||||
'affine:surface': 3,
|
||||
},
|
||||
space
|
||||
);
|
||||
});
|
||||
if ('affine:database' in versions) {
|
||||
versions['affine:database'] = 3;
|
||||
meta.set('blockVersions', new YMap(Object.entries(versions)));
|
||||
} else {
|
||||
versions.set('affine:database', 3);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
export enum WorkspaceVersion {
|
||||
// v1 is treated as undefined
|
||||
SubDoc = 2,
|
||||
DatabaseV3 = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* If returns false, it means no migration is needed.
|
||||
* If returns true, it means migration is done.
|
||||
* If returns Workspace, it means new workspace is created,
|
||||
* and the old workspace should be deleted.
|
||||
*/
|
||||
export async function migrateWorkspace(
|
||||
currentVersion: WorkspaceVersion | undefined,
|
||||
options: UpgradeOptions
|
||||
): Promise<Workspace | boolean> {
|
||||
if (currentVersion === undefined) {
|
||||
const workspace = await upgradeV1ToV2(options);
|
||||
await upgradeV2ToV3({
|
||||
...options,
|
||||
getCurrentRootDoc: () => Promise.resolve(workspace.doc),
|
||||
});
|
||||
return workspace;
|
||||
}
|
||||
if (currentVersion === WorkspaceVersion.SubDoc) {
|
||||
return upgradeV2ToV3(options);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function migrateLocalBlobStorage(from: string, to: string) {
|
||||
const fromStorage = createIndexeddbStorage(from);
|
||||
const toStorage = createIndexeddbStorage(to);
|
||||
const keys = await fromStorage.crud.list();
|
||||
for (const key of keys) {
|
||||
const value = await fromStorage.crud.get(key);
|
||||
if (!value) {
|
||||
console.warn('cannot find blob:', key);
|
||||
continue;
|
||||
}
|
||||
await toStorage.crud.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ export default defineConfig({
|
||||
'rxjs',
|
||||
'zod',
|
||||
'react',
|
||||
'yjs',
|
||||
/^jotai/,
|
||||
/^@blocksuite/,
|
||||
/^@affine\/templates/,
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
"jotai": "^2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/block-std": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/block-std": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"lottie-web": "^5.12.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -23,5 +23,5 @@
|
||||
"@blocksuite/store": "*",
|
||||
"lottie-web": "*"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
15
packages/native/__tests__/db.spec.mts
Normal file
15
packages/native/__tests__/db.spec.mts
Normal file
@@ -0,0 +1,15 @@
|
||||
import assert from 'node:assert';
|
||||
import { test } from 'node:test';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { SqliteConnection, ValidationResult } from '../index';
|
||||
|
||||
test('db', { concurrency: false }, async t => {
|
||||
await t.test('validate', async () => {
|
||||
const path = fileURLToPath(
|
||||
new URL('./fixtures/test01.affine', import.meta.url)
|
||||
);
|
||||
const result = await SqliteConnection.validate(path);
|
||||
assert.equal(result, ValidationResult.MissingVersionColumn);
|
||||
});
|
||||
});
|
||||
BIN
packages/native/__tests__/fixtures/test01.affine
Normal file
BIN
packages/native/__tests__/fixtures/test01.affine
Normal file
Binary file not shown.
7
packages/native/index.d.ts
vendored
7
packages/native/index.d.ts
vendored
@@ -41,8 +41,9 @@ export interface InsertRow {
|
||||
export enum ValidationResult {
|
||||
MissingTables = 0,
|
||||
MissingDocIdColumn = 1,
|
||||
GeneralError = 2,
|
||||
Valid = 3,
|
||||
MissingVersionColumn = 2,
|
||||
GeneralError = 3,
|
||||
Valid = 4,
|
||||
}
|
||||
export class Subscription {
|
||||
toString(): string;
|
||||
@@ -75,6 +76,8 @@ export class SqliteConnection {
|
||||
docId: string | undefined | null,
|
||||
updates: Array<InsertRow>
|
||||
): Promise<void>;
|
||||
initVersion(): Promise<void>;
|
||||
setVersion(version: number): Promise<void>;
|
||||
close(): Promise<void>;
|
||||
get isClose(): boolean;
|
||||
static validate(path: string): Promise<ValidationResult>;
|
||||
|
||||
@@ -38,5 +38,5 @@
|
||||
"test": "cross-env TS_NODE_TRANSPILE_ONLY=1 TS_NODE_PROJECT=./tsconfig.json node --test --loader ts-node/esm --experimental-specifier-resolution=node ./__tests__/**/*.mts",
|
||||
"version": "napi version"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -11,4 +11,9 @@ CREATE TABLE IF NOT EXISTS "blobs" (
|
||||
key TEXT PRIMARY KEY NOT NULL,
|
||||
data BLOB NOT NULL,
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);"#;
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "version_info" (
|
||||
version NUMBER NOT NULL,
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
)
|
||||
"#;
|
||||
|
||||
@@ -7,6 +7,9 @@ use sqlx::{
|
||||
Pool, Row,
|
||||
};
|
||||
|
||||
// latest version
|
||||
const LATEST_VERSION: i32 = 3;
|
||||
|
||||
#[napi(object)]
|
||||
pub struct BlobRow {
|
||||
pub key: String,
|
||||
@@ -38,6 +41,7 @@ pub struct SqliteConnection {
|
||||
pub enum ValidationResult {
|
||||
MissingTables,
|
||||
MissingDocIdColumn,
|
||||
MissingVersionColumn,
|
||||
GeneralError,
|
||||
Valid,
|
||||
}
|
||||
@@ -228,6 +232,39 @@ impl SqliteConnection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub async fn init_version(&self) -> napi::Result<()> {
|
||||
// create version_info table
|
||||
sqlx::query!(
|
||||
"CREATE TABLE IF NOT EXISTS version_info (
|
||||
version NUMBER NOT NULL,
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
)"
|
||||
)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(anyhow::Error::from)?;
|
||||
// `3` is the first version that has version_info table,
|
||||
// do not modify the version number.
|
||||
sqlx::query!("INSERT INTO version_info (version) VALUES (3)")
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(anyhow::Error::from)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub async fn set_version(&self, version: i32) -> napi::Result<()> {
|
||||
if version > LATEST_VERSION {
|
||||
return Err(anyhow::Error::msg("Version is too new").into());
|
||||
}
|
||||
sqlx::query!("UPDATE version_info SET version = ?", version)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(anyhow::Error::from)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub async fn close(&self) {
|
||||
self.pool.close().await;
|
||||
@@ -261,6 +298,18 @@ impl SqliteConnection {
|
||||
Err(_) => return ValidationResult::GeneralError,
|
||||
};
|
||||
|
||||
let tables_res = sqlx::query("SELECT name FROM sqlite_master WHERE type='table'")
|
||||
.fetch_all(&pool)
|
||||
.await;
|
||||
|
||||
let version_exist = match tables_res {
|
||||
Ok(res) => {
|
||||
let names: Vec<String> = res.iter().map(|row| row.get(0)).collect();
|
||||
names.contains(&"version_info".to_string())
|
||||
}
|
||||
Err(_) => return ValidationResult::GeneralError,
|
||||
};
|
||||
|
||||
let columns_res = sqlx::query("PRAGMA table_info(updates)")
|
||||
.fetch_all(&pool)
|
||||
.await;
|
||||
@@ -277,6 +326,8 @@ impl SqliteConnection {
|
||||
ValidationResult::MissingTables
|
||||
} else if !doc_id_exist {
|
||||
ValidationResult::MissingDocIdColumn
|
||||
} else if !version_exist {
|
||||
ValidationResult::MissingVersionColumn
|
||||
} else {
|
||||
ValidationResult::Valid
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/plugin-cli",
|
||||
"type": "module",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"bin": {
|
||||
"af": "./src/af.mjs"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/sdk",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
@@ -22,9 +22,9 @@
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"jotai": "^2.3.1",
|
||||
"zod": "^3.22.1"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/storage",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"engines": {
|
||||
"node": ">= 10.16.0 < 11 || >= 11.8.0"
|
||||
},
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
"./v1/*.json": "./v1/*.json",
|
||||
"./preloading.json": "./preloading.json"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@affine/workers",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "wrangler dev"
|
||||
|
||||
@@ -34,5 +34,5 @@
|
||||
"@types/ws": "^8.5.5",
|
||||
"ws": "^8.13.0"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { WorkspaceAdapter } from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import type { BlockHub } from '@blocksuite/blocks';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { WorkspaceVersion } from '@toeverything/infra/blocksuite';
|
||||
import { atom } from 'jotai';
|
||||
import { z } from 'zod';
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import { migrateToSubdoc } from '@affine/env/blocksuite';
|
||||
import type { LocalWorkspace } from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { getOrCreateWorkspace } from '@affine/workspace/manager';
|
||||
import { nanoid, Workspace } from '@blocksuite/store';
|
||||
import { createIndexeddbStorage } from '@blocksuite/store';
|
||||
const Y = Workspace.Y;
|
||||
|
||||
export function upgradeV1ToV2(oldWorkspace: LocalWorkspace): LocalWorkspace {
|
||||
const oldDoc = oldWorkspace.blockSuiteWorkspace.doc;
|
||||
const newDoc = migrateToSubdoc(oldDoc);
|
||||
if (newDoc === oldDoc) {
|
||||
console.warn('do not need update');
|
||||
return oldWorkspace;
|
||||
} else {
|
||||
const id = nanoid();
|
||||
const newBlockSuiteWorkspace = getOrCreateWorkspace(
|
||||
id,
|
||||
WorkspaceFlavour.LOCAL
|
||||
);
|
||||
Y.applyUpdate(newBlockSuiteWorkspace.doc, Y.encodeStateAsUpdate(newDoc));
|
||||
newDoc.getSubdocs().forEach(subdoc => {
|
||||
newBlockSuiteWorkspace.doc.getSubdocs().forEach(newDoc => {
|
||||
if (subdoc.guid === newDoc.guid) {
|
||||
Y.applyUpdate(newDoc, Y.encodeStateAsUpdate(subdoc));
|
||||
}
|
||||
});
|
||||
});
|
||||
console.log('migration result', newBlockSuiteWorkspace.doc.toJSON());
|
||||
|
||||
return {
|
||||
blockSuiteWorkspace: newBlockSuiteWorkspace,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
id,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function migrateLocalBlobStorage(from: string, to: string) {
|
||||
const fromStorage = createIndexeddbStorage(from);
|
||||
const toStorage = createIndexeddbStorage(to);
|
||||
const keys = await fromStorage.crud.list();
|
||||
for (const key of keys) {
|
||||
const value = await fromStorage.crud.get(key);
|
||||
if (!value) {
|
||||
console.warn('cannot find blob:', key);
|
||||
continue;
|
||||
}
|
||||
await toStorage.crud.set(key, value);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@toeverything/y-indexeddb",
|
||||
"type": "module",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"description": "IndexedDB database adapter for Yjs",
|
||||
"repository": "toeverything/AFFiNE",
|
||||
"author": "toeverything",
|
||||
@@ -37,8 +37,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@affine/y-provider": "workspace:*",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-dts": "3.5.2",
|
||||
"y-indexeddb": "^9.0.11"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/y-provider",
|
||||
"type": "module",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"description": "Yjs provider utilities for AFFiNE",
|
||||
"main": "./src/index.ts",
|
||||
"module": "./src/index.ts",
|
||||
@@ -9,7 +9,7 @@
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"yjs": "^13.5.51"
|
||||
|
||||
@@ -52,7 +52,7 @@ export const createLazyProvider = (
|
||||
const changeStatus = (newStatus: Status) => {
|
||||
// simulate a stack, each syncing and synced should be paired
|
||||
if (newStatus.type === 'idle') {
|
||||
if (syncingStack !== 0) {
|
||||
if (connected && syncingStack !== 0) {
|
||||
console.error('syncingStatus !== 0, this should not happen');
|
||||
}
|
||||
syncingStack = 0;
|
||||
@@ -79,6 +79,9 @@ export const createLazyProvider = (
|
||||
|
||||
async function syncDoc(doc: Doc) {
|
||||
const guid = doc.guid;
|
||||
if (!connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
changeStatus({
|
||||
type: 'syncing',
|
||||
@@ -87,6 +90,18 @@ export const createLazyProvider = (
|
||||
.queryDocState(guid, {
|
||||
stateVector: encodeStateVector(doc),
|
||||
})
|
||||
.then(remoteUpdate => {
|
||||
if (!connected) {
|
||||
changeStatus({
|
||||
type: 'idle',
|
||||
});
|
||||
return;
|
||||
}
|
||||
changeStatus({
|
||||
type: 'synced',
|
||||
});
|
||||
return remoteUpdate;
|
||||
})
|
||||
.catch(error => {
|
||||
changeStatus({
|
||||
type: 'error',
|
||||
@@ -94,9 +109,6 @@ export const createLazyProvider = (
|
||||
});
|
||||
throw error;
|
||||
});
|
||||
changeStatus({
|
||||
type: 'synced',
|
||||
});
|
||||
|
||||
pendingMap.set(guid, []);
|
||||
|
||||
@@ -171,6 +183,9 @@ export const createLazyProvider = (
|
||||
*/
|
||||
function setupDatasourceListeners() {
|
||||
datasourceUnsub = datasource.onDocUpdate?.((guid, update) => {
|
||||
if (!connected) {
|
||||
return;
|
||||
}
|
||||
changeStatus({
|
||||
type: 'syncing',
|
||||
});
|
||||
@@ -244,16 +259,25 @@ export const createLazyProvider = (
|
||||
});
|
||||
// root doc should be already loaded,
|
||||
// but we want to populate the cache for later update events
|
||||
connectDoc(rootDoc).catch(error => {
|
||||
changeStatus({
|
||||
type: 'error',
|
||||
error,
|
||||
connectDoc(rootDoc)
|
||||
.then(() => {
|
||||
if (!connected) {
|
||||
changeStatus({
|
||||
type: 'idle',
|
||||
});
|
||||
return;
|
||||
}
|
||||
changeStatus({
|
||||
type: 'synced',
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
changeStatus({
|
||||
type: 'error',
|
||||
error,
|
||||
});
|
||||
console.error(error);
|
||||
});
|
||||
console.error(error);
|
||||
});
|
||||
changeStatus({
|
||||
type: 'synced',
|
||||
});
|
||||
setupDatasourceListeners();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/bookmark-plugin",
|
||||
"type": "module",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"description": "Bookmark Plugin",
|
||||
"affinePlugin": {
|
||||
"release": true,
|
||||
|
||||
@@ -35,5 +35,5 @@
|
||||
"react": "*",
|
||||
"react-dom": "*"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"description": "Hello world plugin",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"scripts": {
|
||||
"dev": "af dev",
|
||||
"build": "af build"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/image-preview-plugin",
|
||||
"type": "module",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"description": "Image preview plugin",
|
||||
"affinePlugin": {
|
||||
"release": true,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"description": "Outline plugin",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"scripts": {
|
||||
"dev": "af dev",
|
||||
"build": "af build"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"description": "Vue hello world plugin",
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"scripts": {
|
||||
"dev": "af dev",
|
||||
"build": "af build"
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
"devDependencies": {
|
||||
"@affine-test/fixtures": "workspace:*",
|
||||
"@affine-test/kit": "workspace:*",
|
||||
"@blocksuite/block-std": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/block-std": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@playwright/test": "^1.37.0",
|
||||
"express": "^4.18.2",
|
||||
"http-proxy-middleware": "^3.0.0-beta.1",
|
||||
"serve": "^14.2.0"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
"devDependencies": {
|
||||
"@affine-test/fixtures": "workspace:*",
|
||||
"@affine-test/kit": "workspace:*",
|
||||
"@blocksuite/block-std": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230821151132-2bd0c7f6-nightly",
|
||||
"@blocksuite/block-std": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230830111255-92eab248-nightly",
|
||||
"@playwright/test": "^1.37.0",
|
||||
"express": "^4.18.2",
|
||||
"http-proxy-middleware": "^3.0.0-beta.1",
|
||||
"serve": "^14.2.0"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -120,6 +120,16 @@ test('Create a new page and search this page', async ({ page }) => {
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForTimeout(300);
|
||||
await assertTitle(page, 'test123456');
|
||||
|
||||
await page.reload();
|
||||
await waitEditorLoad(page);
|
||||
await openQuickSearchByShortcut(page);
|
||||
await page.keyboard.insertText('test123456');
|
||||
await page.waitForTimeout(300);
|
||||
await assertResultList(page, ['test123456']);
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForTimeout(300);
|
||||
await assertTitle(page, 'test123456');
|
||||
});
|
||||
test('Navigate to the 404 page and try to open quick search', async ({
|
||||
page,
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"@affine-test/kit": "workspace:*",
|
||||
"@playwright/test": "^1.37.0"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"@affine-test/kit": "workspace:*",
|
||||
"@playwright/test": "^1.37.0"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"@affine-test/kit": "workspace:*",
|
||||
"@playwright/test": "^1.37.0"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
2
tests/fixtures/package.json
vendored
2
tests/fixtures/package.json
vendored
@@ -3,5 +3,5 @@
|
||||
"exports": {
|
||||
"./*": "./*"
|
||||
},
|
||||
"version": "0.8.0-beta.2"
|
||||
"version": "0.8.3"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine-test/kit",
|
||||
"private": true,
|
||||
"version": "0.8.0-beta.2",
|
||||
"version": "0.8.3",
|
||||
"exports": {
|
||||
"./playwright": "./playwright.ts",
|
||||
"./utils/*": "./utils/*.ts"
|
||||
|
||||
285
yarn.lock
285
yarn.lock
@@ -25,10 +25,10 @@ __metadata:
|
||||
dependencies:
|
||||
"@affine-test/fixtures": "workspace:*"
|
||||
"@affine-test/kit": "workspace:*"
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@playwright/test": ^1.37.0
|
||||
express: ^4.18.2
|
||||
http-proxy-middleware: ^3.0.0-beta.1
|
||||
@@ -42,10 +42,10 @@ __metadata:
|
||||
dependencies:
|
||||
"@affine-test/fixtures": "workspace:*"
|
||||
"@affine-test/kit": "workspace:*"
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@playwright/test": ^1.37.0
|
||||
express: ^4.18.2
|
||||
http-proxy-middleware: ^3.0.0-beta.1
|
||||
@@ -136,12 +136,12 @@ __metadata:
|
||||
"@affine/i18n": "workspace:*"
|
||||
"@affine/jotai": "workspace:*"
|
||||
"@affine/workspace": "workspace:*"
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/icons": ^2.1.31
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@dnd-kit/core": ^6.0.8
|
||||
"@dnd-kit/sortable": ^7.0.2
|
||||
"@emotion/cache": ^11.11.0
|
||||
@@ -226,13 +226,13 @@ __metadata:
|
||||
"@affine/jotai": "workspace:*"
|
||||
"@affine/templates": "workspace:*"
|
||||
"@affine/workspace": "workspace:*"
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/icons": ^2.1.31
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@dnd-kit/core": ^6.0.8
|
||||
"@dnd-kit/sortable": ^7.0.2
|
||||
"@emotion/cache": ^11.11.0
|
||||
@@ -305,12 +305,12 @@ __metadata:
|
||||
resolution: "@affine/docs@workspace:apps/docs"
|
||||
dependencies:
|
||||
"@affine/component": "workspace:*"
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@types/react": ^18.2.20
|
||||
"@types/react-dom": ^18.2.7
|
||||
"@vanilla-extract/css": ^1.12.0
|
||||
@@ -335,10 +335,10 @@ __metadata:
|
||||
"@affine/env": "workspace:*"
|
||||
"@affine/native": "workspace:*"
|
||||
"@affine/sdk": "workspace:*"
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@electron-forge/cli": ^6.4.0
|
||||
"@electron-forge/core": ^6.4.0
|
||||
"@electron-forge/core-utils": ^6.4.0
|
||||
@@ -360,6 +360,7 @@ __metadata:
|
||||
electron-window-state: ^5.0.3
|
||||
esbuild: ^0.19.2
|
||||
fs-extra: ^11.1.1
|
||||
glob: ^10.3.3
|
||||
jotai: ^2.3.1
|
||||
link-preview-js: ^3.0.5
|
||||
lodash-es: ^4.17.21
|
||||
@@ -381,7 +382,7 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/env@workspace:packages/env"
|
||||
dependencies:
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
lit: ^2.8.0
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0
|
||||
@@ -455,12 +456,12 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/jotai@workspace:packages/jotai"
|
||||
dependencies:
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
jotai: ^2.3.1
|
||||
lottie-web: ^5.12.2
|
||||
peerDependencies:
|
||||
@@ -598,13 +599,13 @@ __metadata:
|
||||
"@affine/jotai": "workspace:*"
|
||||
"@affine/templates": "workspace:*"
|
||||
"@affine/workspace": "workspace:*"
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/icons": ^2.1.31
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@toeverything/hooks": "workspace:*"
|
||||
"@toeverything/y-indexeddb": "workspace:*"
|
||||
"@types/react": ^18.2.20
|
||||
@@ -621,9 +622,9 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/sdk@workspace:packages/sdk"
|
||||
dependencies:
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
jotai: ^2.3.1
|
||||
vite: ^4.4.9
|
||||
vite-plugin-dts: 3.5.2
|
||||
@@ -696,13 +697,13 @@ __metadata:
|
||||
dependencies:
|
||||
"@affine/component": "workspace:*"
|
||||
"@affine/i18n": "workspace:*"
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/icons": ^2.1.31
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@storybook/addon-actions": ^7.3.1
|
||||
"@storybook/addon-essentials": ^7.3.1
|
||||
"@storybook/addon-interactions": ^7.3.1
|
||||
@@ -795,7 +796,7 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/y-provider@workspace:packages/y-provider"
|
||||
dependencies:
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
peerDependencies:
|
||||
yjs: ^13.5.51
|
||||
languageName: unknown
|
||||
@@ -3385,25 +3386,25 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@blocksuite/block-std@npm:0.0.0-20230821151132-2bd0c7f6-nightly":
|
||||
version: 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
resolution: "@blocksuite/block-std@npm:0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/block-std@npm:0.0.0-20230830111255-92eab248-nightly":
|
||||
version: 0.0.0-20230830111255-92eab248-nightly
|
||||
resolution: "@blocksuite/block-std@npm:0.0.0-20230830111255-92eab248-nightly"
|
||||
dependencies:
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
w3c-keyname: ^2.2.8
|
||||
peerDependencies:
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
checksum: 6bd1aff5677ce1330fb8dd5e294b3e9fb931782d1e3a9d45ae52749f9a43f75bd6667c0496b17b79ca2c676a8e972e88ad606259543c32ed777ea84f5da96572
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
checksum: 9e682758203795dff92dcaef99c19a8456ae442b642bda05f3489cb19798252dd1f5318d8a2db866946725d99bd64ed84ac8d516b0b13da90d849d9026839835
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@blocksuite/blocks@npm:0.0.0-20230821151132-2bd0c7f6-nightly":
|
||||
version: 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
resolution: "@blocksuite/blocks@npm:0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/blocks@npm:0.0.0-20230830111255-92eab248-nightly":
|
||||
version: 0.0.0-20230830111255-92eab248-nightly
|
||||
resolution: "@blocksuite/blocks@npm:0.0.0-20230830111255-92eab248-nightly"
|
||||
dependencies:
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/phasor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/virgo": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/phasor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/virgo": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@floating-ui/dom": ^1.5.1
|
||||
"@types/webfontloader": ^1.6.35
|
||||
buffer: ^6.0.3
|
||||
@@ -3411,51 +3412,51 @@ __metadata:
|
||||
file-type: ^16.5.4
|
||||
html2canvas: ^1.4.1
|
||||
jszip: ^3.10.1
|
||||
lit: ^2.7.6
|
||||
lit: ^2.8.0
|
||||
marked: ^4.3.0
|
||||
pdf-lib: ^1.17.1
|
||||
shiki: ^0.14.3
|
||||
sortablejs: ^1.15.0
|
||||
turndown: ^7.1.2
|
||||
webfontloader: ^1.6.28
|
||||
zod: ^3.21.4
|
||||
zod: ^3.22.2
|
||||
peerDependencies:
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@toeverything/theme": ^0.7.12
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@toeverything/theme": ^0.7.13
|
||||
yjs: ^13
|
||||
checksum: faff415c28631e1c0ace833ba3597b76962a17bc5290a4566b2d0f13d998b685b55965eec82e8ac4ee67a7b8e7c5784f705741ff0ad3cd3246989fd7a62170ef
|
||||
checksum: 14c58a5bccc6ce23ae4e71114bc260fec7e764ba24588738124c49869bc06f38f450ad46086cd964a3c740028336e561ebd442fdf2c3ff7ee5bce763ccbfa0a5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@blocksuite/editor@npm:0.0.0-20230821151132-2bd0c7f6-nightly":
|
||||
version: 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
resolution: "@blocksuite/editor@npm:0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/editor@npm:0.0.0-20230830111255-92eab248-nightly":
|
||||
version: 0.0.0-20230830111255-92eab248-nightly
|
||||
resolution: "@blocksuite/editor@npm:0.0.0-20230830111255-92eab248-nightly"
|
||||
dependencies:
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
lit: ^2.7.6
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
lit: ^2.8.0
|
||||
peerDependencies:
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@toeverything/theme": ^0.7.12
|
||||
checksum: 64c83e89b4dd04783614455c5ab13494fa9383e0b626e1b4aa3c516144548c037e73eb9128fd07930c335965130c81741490536f56e387a1c03ba9fc45a16a24
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@toeverything/theme": ^0.7.13
|
||||
checksum: ba2dcfa03ef0be06e0f0be022f301ea095b093d83aeab41ca8c5dcd0450c5e7cba6c8e5d3f99c383f6aa97e16b1967e4d9e884d8a827ca7aeda8bc12a31d44d0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@blocksuite/global@npm:0.0.0-20230821151132-2bd0c7f6-nightly":
|
||||
version: 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
resolution: "@blocksuite/global@npm:0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/global@npm:0.0.0-20230830111255-92eab248-nightly":
|
||||
version: 0.0.0-20230830111255-92eab248-nightly
|
||||
resolution: "@blocksuite/global@npm:0.0.0-20230830111255-92eab248-nightly"
|
||||
dependencies:
|
||||
ansi-colors: ^4.1.3
|
||||
zod: ^3.21.4
|
||||
zod: ^3.22.2
|
||||
peerDependencies:
|
||||
lit: ^2.7
|
||||
peerDependenciesMeta:
|
||||
lit:
|
||||
optional: true
|
||||
checksum: cd5339742d6f5c01221ea4653f56b98e7b48482d9aa1173450db84ae8849fe52d4c205f7a43089079c3e5efca0ad3f40f5a3e7eae359d032540db7444dfe3c84
|
||||
checksum: 723fb9f8e8e3b0cd9c13c4b92dd8e04c0a580b09301af9bf59460974a58137570fc39c8a1f4488a39483b133f1856b663e46254138f3d61545e3ea3c128b0e3b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -3469,67 +3470,66 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@blocksuite/lit@npm:0.0.0-20230821151132-2bd0c7f6-nightly":
|
||||
version: 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
resolution: "@blocksuite/lit@npm:0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/lit@npm:0.0.0-20230830111255-92eab248-nightly":
|
||||
version: 0.0.0-20230830111255-92eab248-nightly
|
||||
resolution: "@blocksuite/lit@npm:0.0.0-20230830111255-92eab248-nightly"
|
||||
dependencies:
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/virgo": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
lit: ^2.7.6
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/virgo": 0.0.0-20230830111255-92eab248-nightly
|
||||
lit: ^2.8.0
|
||||
peerDependencies:
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
checksum: 8686c5dae150318be527553ab6ed67f5e01f0eb888e9691e1a0d78df6b38c98873704be10074ae4d18aa1fa84c293e97d082ab6751d64e95cbe8f71868bf6b2a
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
checksum: b7d81746b26930635bdf3539d6c1672135dc0452ba1837f27862e82c49b0f0fe4c576fc2319c4b6e8cfeeb5cf3af5834380aa43882e7037cdf8a0711430e0e29
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@blocksuite/phasor@npm:0.0.0-20230821151132-2bd0c7f6-nightly":
|
||||
version: 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
resolution: "@blocksuite/phasor@npm:0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/phasor@npm:0.0.0-20230830111255-92eab248-nightly":
|
||||
version: 0.0.0-20230830111255-92eab248-nightly
|
||||
resolution: "@blocksuite/phasor@npm:0.0.0-20230830111255-92eab248-nightly"
|
||||
dependencies:
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
fractional-indexing: ^3.2.0
|
||||
peerDependencies:
|
||||
nanoid: ^4
|
||||
yjs: ^13
|
||||
checksum: 8dfd31e3e711629508ab0f406764d674ade5f9f9530aea9fce4615b1b2702b02d69804f096c9e8f8d059f6d2d39341e6e3516c2490969db42fec4ece96453b5e
|
||||
checksum: eae34ff320060daa11605a7433acdadcee53b85419f6bdca33bb0cb8d6659fe729425abee450667284b02ff6846377627aa5583fbc607601cdc678031ef6967e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@blocksuite/store@npm:0.0.0-20230821151132-2bd0c7f6-nightly":
|
||||
version: 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
resolution: "@blocksuite/store@npm:0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/store@npm:0.0.0-20230830111255-92eab248-nightly":
|
||||
version: 0.0.0-20230830111255-92eab248-nightly
|
||||
resolution: "@blocksuite/store@npm:0.0.0-20230830111255-92eab248-nightly"
|
||||
dependencies:
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/virgo": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/virgo": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@types/flexsearch": ^0.7.3
|
||||
buffer: ^6.0.3
|
||||
flexsearch: 0.7.21
|
||||
idb-keyval: ^6.2.1
|
||||
ky: ^0.33.3
|
||||
lib0: ^0.2.78
|
||||
lib0: ^0.2.83
|
||||
merge: ^2.1.1
|
||||
minimatch: ^9.0.3
|
||||
nanoid: ^4.0.2
|
||||
y-protocols: ^1.0.5
|
||||
zod: ^3.21.4
|
||||
zod: ^3.22.2
|
||||
peerDependencies:
|
||||
async-call-rpc: ^6
|
||||
yjs: ^13
|
||||
checksum: 284f72e56b64fac0949cef1fb3ebc9b71a1a0c44f33a3a252129c882e9d05110e164c7055d909b392715042ad6eb44ae37219480c2b73349a82897459aaaaec4
|
||||
checksum: eedd18d53e6ed89e759bdd1b8cab44641ba5f4135715c2f1f7b6860cd0aa9453f225c60db17da591b8a97717bd809bf42e8abf07f157b0ab886c0d73e8ba4f7b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@blocksuite/virgo@npm:0.0.0-20230821151132-2bd0c7f6-nightly":
|
||||
version: 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
resolution: "@blocksuite/virgo@npm:0.0.0-20230821151132-2bd0c7f6-nightly"
|
||||
"@blocksuite/virgo@npm:0.0.0-20230830111255-92eab248-nightly":
|
||||
version: 0.0.0-20230830111255-92eab248-nightly
|
||||
resolution: "@blocksuite/virgo@npm:0.0.0-20230830111255-92eab248-nightly"
|
||||
dependencies:
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
zod: ^3.21.4
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
zod: ^3.22.2
|
||||
peerDependencies:
|
||||
lit: ^2.7
|
||||
yjs: ^13
|
||||
checksum: 3fc280a0b21e9a5aef4a949bc0713096c84762a18ee9b4ac7cf5c898019ea9a6a4ad8f580f295c4f353554de2332b4d0d190fea8bf9221418339783e889a3be2
|
||||
checksum: cf545c10e381c01c46fc776fbd692d28d630c2aa169e60f6e8b7696d6512a47434119b65f8b4299ab77a1b9b53f8af606db692fb0617cdcecce0aeddfa500024
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11738,12 +11738,12 @@ __metadata:
|
||||
dependencies:
|
||||
"@affine/env": "workspace:*"
|
||||
"@affine/y-provider": "workspace:*"
|
||||
"@blocksuite/block-std": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/block-std": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
foxact: ^0.2.20
|
||||
peerDependencies:
|
||||
"@affine/y-provider": "workspace:*"
|
||||
@@ -11778,17 +11778,18 @@ __metadata:
|
||||
resolution: "@toeverything/infra@workspace:packages/infra"
|
||||
dependencies:
|
||||
"@affine/sdk": "workspace:*"
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/global": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/editor": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/global": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/lit": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
async-call-rpc: ^6.3.1
|
||||
electron: "link:../../apps/electron/node_modules/electron"
|
||||
jotai: ^2.3.1
|
||||
react: ^18.2.0
|
||||
vite: ^4.4.9
|
||||
vite-plugin-dts: 3.5.2
|
||||
yjs: ^13.6.7
|
||||
zod: ^3.22.1
|
||||
peerDependencies:
|
||||
"@affine/templates": "*"
|
||||
@@ -11797,6 +11798,7 @@ __metadata:
|
||||
async-call-rpc: "*"
|
||||
electron: "*"
|
||||
react: "*"
|
||||
yjs: ^13
|
||||
peerDependenciesMeta:
|
||||
"@affine/templates":
|
||||
optional: true
|
||||
@@ -11810,6 +11812,8 @@ __metadata:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
yjs:
|
||||
optional: true
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -11825,8 +11829,8 @@ __metadata:
|
||||
resolution: "@toeverything/y-indexeddb@workspace:packages/y-indexeddb"
|
||||
dependencies:
|
||||
"@affine/y-provider": "workspace:*"
|
||||
"@blocksuite/blocks": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/store": 0.0.0-20230821151132-2bd0c7f6-nightly
|
||||
"@blocksuite/blocks": 0.0.0-20230830111255-92eab248-nightly
|
||||
"@blocksuite/store": 0.0.0-20230830111255-92eab248-nightly
|
||||
idb: ^7.1.1
|
||||
vite: ^4.4.9
|
||||
vite-plugin-dts: 3.5.2
|
||||
@@ -20588,7 +20592,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:^10.0.0, glob@npm:^10.2.2":
|
||||
"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.3":
|
||||
version: 10.3.3
|
||||
resolution: "glob@npm:10.3.3"
|
||||
dependencies:
|
||||
@@ -23943,7 +23947,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lib0@npm:^0.2.42, lib0@npm:^0.2.74, lib0@npm:^0.2.78, lib0@npm:^0.2.82":
|
||||
"lib0@npm:^0.2.42, lib0@npm:^0.2.74, lib0@npm:^0.2.82":
|
||||
version: 0.2.82
|
||||
resolution: "lib0@npm:0.2.82"
|
||||
dependencies:
|
||||
@@ -23955,6 +23959,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lib0@npm:^0.2.83":
|
||||
version: 0.2.83
|
||||
resolution: "lib0@npm:0.2.83"
|
||||
dependencies:
|
||||
isomorphic.js: ^0.2.4
|
||||
bin:
|
||||
0gentesthtml: bin/gentesthtml.js
|
||||
0serve: bin/0serve.js
|
||||
checksum: 2c05609146b25c14a72c99683f6f71e10c74b60be39618f25117d3f03a2435b6d6219876641fa019fe1acde7fdfa75dc3eb3a23e37c9ae30eae7be05225e2263
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lie@npm:~3.3.0":
|
||||
version: 3.3.0
|
||||
resolution: "lie@npm:3.3.0"
|
||||
@@ -24098,7 +24114,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lit@npm:^2.7.6, lit@npm:^2.8.0":
|
||||
"lit@npm:^2.8.0":
|
||||
version: 2.8.0
|
||||
resolution: "lit@npm:2.8.0"
|
||||
dependencies:
|
||||
@@ -33846,6 +33862,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zod@npm:^3.22.2":
|
||||
version: 3.22.2
|
||||
resolution: "zod@npm:3.22.2"
|
||||
checksum: 231e2180c8eabb56e88680d80baff5cf6cbe6d64df3c44c50ebe52f73081ecd0229b1c7215b9552537f537a36d9e36afac2737ddd86dc14e3519bdbc777e82b9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zx@npm:^7.2.3":
|
||||
version: 7.2.3
|
||||
resolution: "zx@npm:7.2.3"
|
||||
|
||||
Reference in New Issue
Block a user