mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 00:11:33 +03:00
feat: support get datasource status (#3645)
This commit is contained in:
parent
05144abd6a
commit
dafd5619e6
62
.github/workflows/build.yml
vendored
62
.github/workflows/build.yml
vendored
@ -59,6 +59,25 @@ jobs:
|
|||||||
- name: Run Type Check
|
- name: Run Type Check
|
||||||
run: yarn typecheck
|
run: yarn typecheck
|
||||||
|
|
||||||
|
build-prototype:
|
||||||
|
name: Build Prototype
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: development
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: ./.github/actions/setup-node
|
||||||
|
with:
|
||||||
|
electron-install: false
|
||||||
|
- name: Build Prototype
|
||||||
|
run: yarn nx build prototype
|
||||||
|
- name: Upload prototype artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: prototype
|
||||||
|
path: ./apps/prototype/dist
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
build-server:
|
build-server:
|
||||||
name: Build Server
|
name: Build Server
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -280,6 +299,49 @@ jobs:
|
|||||||
path: ./test-results
|
path: ./test-results
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
|
|
||||||
|
e2e-prototype-test:
|
||||||
|
name: E2E Prototype Test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: development
|
||||||
|
needs: build-prototype
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: ./.github/actions/setup-node
|
||||||
|
with:
|
||||||
|
playwright-install: true
|
||||||
|
electron-install: false
|
||||||
|
- name: Download prototype artifact
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: prototype
|
||||||
|
path: ./apps/prototype/dist
|
||||||
|
- name: Run playwright tests
|
||||||
|
run: yarn e2e --forbid-only
|
||||||
|
working-directory: tests/affine-prototype
|
||||||
|
env:
|
||||||
|
COVERAGE: true
|
||||||
|
|
||||||
|
# - name: Collect code coverage report
|
||||||
|
# run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
|
||||||
|
|
||||||
|
# - name: Upload e2e test coverage results
|
||||||
|
# uses: codecov/codecov-action@v3
|
||||||
|
# with:
|
||||||
|
# token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
# files: ./.coverage/lcov.info
|
||||||
|
# flags: e2etest-prototype
|
||||||
|
# name: affine
|
||||||
|
# fail_ci_if_error: false
|
||||||
|
|
||||||
|
- name: Upload test results
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: test-results-e2e-prototype
|
||||||
|
path: ./test-results
|
||||||
|
if-no-files-found: ignore
|
||||||
|
|
||||||
e2e-test:
|
e2e-test:
|
||||||
name: E2E Test
|
name: E2E Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -8,7 +8,7 @@ AFFiNE Developer Documentation using [waku](https://github.com/dai-shi/waku).
|
|||||||
|
|
||||||
## electron
|
## electron
|
||||||
|
|
||||||
> `web` needs to be built before electron.
|
> `core` needs to be built before electron.
|
||||||
|
|
||||||
AFFiNE Desktop (macOS, Linux and Windows Distribution) using [Electron](https://www.electronjs.org/).
|
AFFiNE Desktop (macOS, Linux and Windows Distribution) using [Electron](https://www.electronjs.org/).
|
||||||
|
|
||||||
@ -20,6 +20,10 @@ Server using [Nest.js](https://nestjs.com/).
|
|||||||
|
|
||||||
Storybook using [Storybook](https://storybook.js.org/).
|
Storybook using [Storybook](https://storybook.js.org/).
|
||||||
|
|
||||||
## Core
|
## prototype
|
||||||
|
|
||||||
AFFiNE Core Application using [React.js](https://reactjs.org/).
|
AFFiNE Prototype using [React.js](https://reactjs.org/) + [Vite](https://vitejs.dev/).
|
||||||
|
|
||||||
|
## core
|
||||||
|
|
||||||
|
AFFiNE Core Application using [React.js](https://reactjs.org/) + [Webpack](https://webpack.js.org/).
|
||||||
|
@ -4,7 +4,6 @@ import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-
|
|||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace';
|
|
||||||
import type { AllWorkspace } from '../../../../shared';
|
import type { AllWorkspace } from '../../../../shared';
|
||||||
import { workspaceAvatarStyle } from './index.css';
|
import { workspaceAvatarStyle } from './index.css';
|
||||||
import {
|
import {
|
||||||
@ -28,9 +27,8 @@ export const WorkspaceSelector = ({
|
|||||||
onClick,
|
onClick,
|
||||||
}: WorkspaceSelectorProps) => {
|
}: WorkspaceSelectorProps) => {
|
||||||
const [name] = useBlockSuiteWorkspaceName(
|
const [name] = useBlockSuiteWorkspaceName(
|
||||||
currentWorkspace?.blockSuiteWorkspace
|
currentWorkspace.blockSuiteWorkspace
|
||||||
);
|
);
|
||||||
const [workspace] = useCurrentWorkspace();
|
|
||||||
|
|
||||||
// Open dialog when `Enter` or `Space` pressed
|
// Open dialog when `Enter` or `Space` pressed
|
||||||
// TODO-Doma Refactor with `@radix-ui/react-dialog` or other libraries that handle these out of the box and be accessible by default
|
// TODO-Doma Refactor with `@radix-ui/react-dialog` or other libraries that handle these out of the box and be accessible by default
|
||||||
@ -57,22 +55,20 @@ export const WorkspaceSelector = ({
|
|||||||
data-testid="workspace-avatar"
|
data-testid="workspace-avatar"
|
||||||
className={workspaceAvatarStyle}
|
className={workspaceAvatarStyle}
|
||||||
size={40}
|
size={40}
|
||||||
workspace={currentWorkspace?.blockSuiteWorkspace ?? null}
|
workspace={currentWorkspace.blockSuiteWorkspace}
|
||||||
/>
|
/>
|
||||||
<StyledSelectorWrapper>
|
<StyledSelectorWrapper>
|
||||||
<StyledWorkspaceName data-testid="workspace-name">
|
<StyledWorkspaceName data-testid="workspace-name">
|
||||||
{name}
|
{name}
|
||||||
</StyledWorkspaceName>
|
</StyledWorkspaceName>
|
||||||
{workspace && (
|
<StyledWorkspaceStatus>
|
||||||
<StyledWorkspaceStatus>
|
{currentWorkspace.flavour === 'local' ? (
|
||||||
{workspace.flavour === 'local' ? (
|
<LocalWorkspaceIcon />
|
||||||
<LocalWorkspaceIcon />
|
) : (
|
||||||
) : (
|
<CloudWorkspaceIcon />
|
||||||
<CloudWorkspaceIcon />
|
)}
|
||||||
)}
|
{currentWorkspace.flavour === 'local' ? 'Local' : 'AFFiNE Cloud'}
|
||||||
{workspace.flavour === 'local' ? 'Local' : 'AFFiNE Cloud'}
|
</StyledWorkspaceStatus>
|
||||||
</StyledWorkspaceStatus>
|
|
||||||
)}
|
|
||||||
</StyledSelectorWrapper>
|
</StyledSelectorWrapper>
|
||||||
</StyledSelectorContainer>
|
</StyledSelectorContainer>
|
||||||
);
|
);
|
||||||
|
5
apps/prototype/README.md
Normal file
5
apps/prototype/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# AFFiNE Prototype
|
||||||
|
|
||||||
|
> This is a prototype of the AFFiNE system to test the feasibility of the approach.
|
||||||
|
>
|
||||||
|
> It is not intended for production use.
|
15
apps/prototype/index.html
Normal file
15
apps/prototype/index.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>AFFiNE Prototype</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="suite/provider-status.html">Provider status test</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
40
apps/prototype/package.json
Normal file
40
apps/prototype/package.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "@affine/prototype",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --host --port 3003",
|
||||||
|
"build": "tsc -b && vite build",
|
||||||
|
"preview": "vite preview --host --port 3003"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@affine-test/fixtures": "workspace:*",
|
||||||
|
"@affine/component": "workspace:*",
|
||||||
|
"@affine/debug": "workspace:*",
|
||||||
|
"@affine/env": "workspace:*",
|
||||||
|
"@affine/graphql": "workspace:*",
|
||||||
|
"@affine/i18n": "workspace:*",
|
||||||
|
"@affine/jotai": "workspace:*",
|
||||||
|
"@affine/templates": "workspace:*",
|
||||||
|
"@affine/workspace": "workspace:*",
|
||||||
|
"@blocksuite/block-std": "0.0.0-20230809030546-32e6e21d-nightly",
|
||||||
|
"@blocksuite/blocks": "0.0.0-20230809030546-32e6e21d-nightly",
|
||||||
|
"@blocksuite/editor": "0.0.0-20230809030546-32e6e21d-nightly",
|
||||||
|
"@blocksuite/global": "0.0.0-20230809030546-32e6e21d-nightly",
|
||||||
|
"@blocksuite/icons": "^2.1.31",
|
||||||
|
"@blocksuite/lit": "0.0.0-20230809030546-32e6e21d-nightly",
|
||||||
|
"@blocksuite/store": "0.0.0-20230809030546-32e6e21d-nightly",
|
||||||
|
"@toeverything/hooks": "workspace:*",
|
||||||
|
"@toeverything/y-indexeddb": "workspace:*",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "^18.2.20",
|
||||||
|
"@types/react-dom": "^18.2.7",
|
||||||
|
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||||
|
"typescript": "^5.1.6",
|
||||||
|
"vite": "^4.4.9"
|
||||||
|
}
|
||||||
|
}
|
16
apps/prototype/project.json
Normal file
16
apps/prototype/project.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "prototype",
|
||||||
|
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||||
|
"projectType": "application",
|
||||||
|
"sourceRoot": "apps/prototype/src",
|
||||||
|
"targets": {
|
||||||
|
"build": {
|
||||||
|
"executor": "nx:run-script",
|
||||||
|
"dependsOn": ["^build"],
|
||||||
|
"options": {
|
||||||
|
"script": "build"
|
||||||
|
},
|
||||||
|
"outputs": ["{projectRoot}/dist"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
apps/prototype/src/provider-status.tsx
Normal file
57
apps/prototype/src/provider-status.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import type { LocalIndexedDBBackgroundProvider } from '@affine/env/workspace';
|
||||||
|
import { createIndexedDBBackgroundProvider } from '@affine/workspace/providers';
|
||||||
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
|
import { useDataSourceStatus } from '@toeverything/hooks/use-data-source-status';
|
||||||
|
import React, { useCallback, useRef } from 'react';
|
||||||
|
import ReactDOM from 'react-dom/client';
|
||||||
|
import { Awareness } from 'y-protocols/awareness';
|
||||||
|
import { Doc } from 'yjs';
|
||||||
|
|
||||||
|
const doc = new Doc();
|
||||||
|
const map = doc.getMap();
|
||||||
|
const awareness = new Awareness(doc);
|
||||||
|
|
||||||
|
const indexeddbProvider = createIndexedDBBackgroundProvider('test', doc, {
|
||||||
|
awareness,
|
||||||
|
}) as LocalIndexedDBBackgroundProvider;
|
||||||
|
indexeddbProvider.connect();
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
const counterRef = useRef(0);
|
||||||
|
const disposeRef = useRef<number>(0);
|
||||||
|
const status = useDataSourceStatus(indexeddbProvider);
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
data-testid="start-button"
|
||||||
|
onClick={useCallback(() => {
|
||||||
|
disposeRef.current = setInterval(() => {
|
||||||
|
const counter = counterRef.current;
|
||||||
|
map.set('counter', counter + 1);
|
||||||
|
counterRef.current = counter + 1;
|
||||||
|
}, 0) as any;
|
||||||
|
}, [])}
|
||||||
|
>
|
||||||
|
start writing
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
data-testid="stop-button"
|
||||||
|
onClick={useCallback(() => {
|
||||||
|
clearInterval(disposeRef.current);
|
||||||
|
}, [])}
|
||||||
|
>
|
||||||
|
stop writing
|
||||||
|
</button>
|
||||||
|
<div data-testid="status">{status.type}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const root = document.getElementById('root');
|
||||||
|
assertExists(root);
|
||||||
|
|
||||||
|
ReactDOM.createRoot(root).render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
1
apps/prototype/src/vite-env.d.ts
vendored
Normal file
1
apps/prototype/src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
12
apps/prototype/suite/provider-status.html
Normal file
12
apps/prototype/suite/provider-status.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Provider status test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="../src/provider-status.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
40
apps/prototype/tsconfig.json
Normal file
40
apps/prototype/tsconfig.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"outDir": "./lib"
|
||||||
|
},
|
||||||
|
"include": ["./src"],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "../../packages/component"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../packages/debug"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../packages/env"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../packages/graphql"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../packages/hooks"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../packages/i18n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../packages/jotai"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../packages/y-indexeddb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../../packages/workspace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
apps/prototype/tsconfig.node.json
Normal file
11
apps/prototype/tsconfig.node.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"outDir": "./lib",
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
22
apps/prototype/vite.config.ts
Normal file
22
apps/prototype/vite.config.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { resolve } from 'node:path';
|
||||||
|
|
||||||
|
import react from '@vitejs/plugin-react-swc';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
target: 'ES2022',
|
||||||
|
sourcemap: true,
|
||||||
|
rollupOptions: {
|
||||||
|
input: {
|
||||||
|
'suite/provider-status': resolve(
|
||||||
|
__dirname,
|
||||||
|
'suite',
|
||||||
|
'provider-status.html'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [react()],
|
||||||
|
});
|
@ -14,7 +14,8 @@
|
|||||||
"tests/kit",
|
"tests/kit",
|
||||||
"tests/affine-legacy/*",
|
"tests/affine-legacy/*",
|
||||||
"tests/affine-local",
|
"tests/affine-local",
|
||||||
"tests/affine-plugin"
|
"tests/affine-plugin",
|
||||||
|
"tests/affine-prototype"
|
||||||
],
|
],
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.16.1 <19.0.0"
|
"node": ">=18.16.1 <19.0.0"
|
||||||
|
6
packages/env/src/blocksuite/index.ts
vendored
6
packages/env/src/blocksuite/index.ts
vendored
@ -2,11 +2,7 @@ import type { Page } from '@blocksuite/store';
|
|||||||
|
|
||||||
export async function initPageWithPreloading(page: Page) {
|
export async function initPageWithPreloading(page: Page) {
|
||||||
const workspace = page.workspace;
|
const workspace = page.workspace;
|
||||||
const {
|
const { data } = await import('@affine/templates/preloading.json');
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-expect-error
|
|
||||||
data,
|
|
||||||
} = await import('@affine/templates/preloading.json');
|
|
||||||
await page.waitForLoaded();
|
await page.waitForLoaded();
|
||||||
await workspace.importPageSnapshot(data['space:hello-world'], page.id);
|
await workspace.importPageSnapshot(data['space:hello-world'], page.id);
|
||||||
}
|
}
|
||||||
|
7
packages/env/src/workspace.ts
vendored
7
packages/env/src/workspace.ts
vendored
@ -1,3 +1,4 @@
|
|||||||
|
import type { StatusAdapter } from '@affine/y-provider';
|
||||||
import type { EditorContainer } from '@blocksuite/editor';
|
import type { EditorContainer } from '@blocksuite/editor';
|
||||||
import type { Page } from '@blocksuite/store';
|
import type { Page } from '@blocksuite/store';
|
||||||
import type {
|
import type {
|
||||||
@ -35,7 +36,9 @@ export interface BroadCastChannelProvider extends PassiveDocProvider {
|
|||||||
/**
|
/**
|
||||||
* Long polling provider with local indexeddb
|
* Long polling provider with local indexeddb
|
||||||
*/
|
*/
|
||||||
export interface LocalIndexedDBBackgroundProvider extends PassiveDocProvider {
|
export interface LocalIndexedDBBackgroundProvider
|
||||||
|
extends StatusAdapter,
|
||||||
|
PassiveDocProvider {
|
||||||
flavour: 'local-indexeddb-background';
|
flavour: 'local-indexeddb-background';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +46,7 @@ export interface LocalIndexedDBDownloadProvider extends ActiveDocProvider {
|
|||||||
flavour: 'local-indexeddb';
|
flavour: 'local-indexeddb';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SQLiteProvider extends PassiveDocProvider {
|
export interface SQLiteProvider extends PassiveDocProvider, StatusAdapter {
|
||||||
flavour: 'sqlite';
|
flavour: 'sqlite';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
packages/env/tsconfig.json
vendored
1
packages/env/tsconfig.json
vendored
@ -4,7 +4,6 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"noEmit": false,
|
"noEmit": false,
|
||||||
"moduleResolution": "Node16",
|
|
||||||
"outDir": "lib"
|
"outDir": "lib"
|
||||||
},
|
},
|
||||||
"references": [
|
"references": [
|
||||||
|
@ -6,10 +6,11 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@affine/env": "workspace:*",
|
"foxact": "^0.2.17"
|
||||||
"@toeverything/y-indexeddb": "workspace:*"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@affine/env": "workspace:*",
|
||||||
|
"@affine/y-provider": "workspace:*",
|
||||||
"@blocksuite/block-std": "0.0.0-20230810005427-25adb757-nightly",
|
"@blocksuite/block-std": "0.0.0-20230810005427-25adb757-nightly",
|
||||||
"@blocksuite/blocks": "0.0.0-20230810005427-25adb757-nightly",
|
"@blocksuite/blocks": "0.0.0-20230810005427-25adb757-nightly",
|
||||||
"@blocksuite/editor": "0.0.0-20230810005427-25adb757-nightly",
|
"@blocksuite/editor": "0.0.0-20230810005427-25adb757-nightly",
|
||||||
@ -18,6 +19,7 @@
|
|||||||
"@blocksuite/store": "0.0.0-20230810005427-25adb757-nightly"
|
"@blocksuite/store": "0.0.0-20230810005427-25adb757-nightly"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
"@affine/y-provider": "workspace:*",
|
||||||
"@blocksuite/block-std": "*",
|
"@blocksuite/block-std": "*",
|
||||||
"@blocksuite/blocks": "*",
|
"@blocksuite/blocks": "*",
|
||||||
"@blocksuite/editor": "*",
|
"@blocksuite/editor": "*",
|
||||||
@ -25,5 +27,31 @@
|
|||||||
"@blocksuite/lit": "*",
|
"@blocksuite/lit": "*",
|
||||||
"@blocksuite/store": "*"
|
"@blocksuite/store": "*"
|
||||||
},
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@affine/env": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@affine/y-provider": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@blocksuite/block-std": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@blocksuite/blocks": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@blocksuite/editor": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@blocksuite/global": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@blocksuite/lit": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@blocksuite/store": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
},
|
||||||
"version": "0.8.0-canary.16"
|
"version": "0.8.0-canary.16"
|
||||||
}
|
}
|
||||||
|
15
packages/hooks/src/use-data-source-status.ts
Normal file
15
packages/hooks/src/use-data-source-status.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import type { Status, StatusAdapter } from '@affine/y-provider';
|
||||||
|
import { useCallback, useSyncExternalStore } from 'react';
|
||||||
|
|
||||||
|
type UIStatus =
|
||||||
|
| Status
|
||||||
|
| {
|
||||||
|
type: 'unknown';
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useDataSourceStatus(datasource: StatusAdapter): UIStatus {
|
||||||
|
return useSyncExternalStore(
|
||||||
|
datasource.subscribeStatusChange,
|
||||||
|
useCallback(() => datasource.status, [datasource])
|
||||||
|
);
|
||||||
|
}
|
@ -26,10 +26,15 @@ const createIndexedDBBackgroundProvider: DocProviderCreator = (
|
|||||||
blockSuiteWorkspace
|
blockSuiteWorkspace
|
||||||
): LocalIndexedDBBackgroundProvider => {
|
): LocalIndexedDBBackgroundProvider => {
|
||||||
const indexeddbProvider = create(blockSuiteWorkspace);
|
const indexeddbProvider = create(blockSuiteWorkspace);
|
||||||
|
|
||||||
let connected = false;
|
let connected = false;
|
||||||
return {
|
return {
|
||||||
flavour: 'local-indexeddb-background',
|
flavour: 'local-indexeddb-background',
|
||||||
passive: true,
|
passive: true,
|
||||||
|
get status() {
|
||||||
|
return indexeddbProvider.status;
|
||||||
|
},
|
||||||
|
subscribeStatusChange: indexeddbProvider.subscribeStatusChange,
|
||||||
get connected() {
|
get connected() {
|
||||||
return connected;
|
return connected;
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
createLazyProvider,
|
createLazyProvider,
|
||||||
type DatasourceDocAdapter,
|
type DatasourceDocAdapter,
|
||||||
} from '@affine/y-provider';
|
} from '@affine/y-provider';
|
||||||
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
import type { DocProviderCreator } from '@blocksuite/store';
|
import type { DocProviderCreator } from '@blocksuite/store';
|
||||||
import { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
import { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
||||||
import type { Doc } from 'yjs';
|
import type { Doc } from 'yjs';
|
||||||
@ -51,6 +52,14 @@ export const createSQLiteProvider: DocProviderCreator = (
|
|||||||
return {
|
return {
|
||||||
flavour: 'sqlite',
|
flavour: 'sqlite',
|
||||||
passive: true,
|
passive: true,
|
||||||
|
get status() {
|
||||||
|
assertExists(provider);
|
||||||
|
return provider.status;
|
||||||
|
},
|
||||||
|
subscribeStatusChange(onStatusChange) {
|
||||||
|
assertExists(provider);
|
||||||
|
return provider.subscribeStatusChange(onStatusChange);
|
||||||
|
},
|
||||||
connect: () => {
|
connect: () => {
|
||||||
datasource = createDatasource(id);
|
datasource = createDatasource(id);
|
||||||
provider = createLazyProvider(rootDoc, datasource, { origin: 'sqlite' });
|
provider = createLazyProvider(rootDoc, datasource, { origin: 'sqlite' });
|
||||||
|
@ -3,6 +3,7 @@ import {
|
|||||||
type DatasourceDocAdapter,
|
type DatasourceDocAdapter,
|
||||||
writeOperation,
|
writeOperation,
|
||||||
} from '@affine/y-provider';
|
} from '@affine/y-provider';
|
||||||
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
import { openDB } from 'idb';
|
import { openDB } from 'idb';
|
||||||
import type { Doc } from 'yjs';
|
import type { Doc } from 'yjs';
|
||||||
import { diffUpdate, mergeUpdates } from 'yjs';
|
import { diffUpdate, mergeUpdates } from 'yjs';
|
||||||
@ -77,7 +78,6 @@ const createDatasource = ({
|
|||||||
const merged = mergeUpdates(rows.map(({ update }) => update));
|
const merged = mergeUpdates(rows.map(({ update }) => update));
|
||||||
rows = [{ timestamp: Date.now(), update: merged }];
|
rows = [{ timestamp: Date.now(), update: merged }];
|
||||||
}
|
}
|
||||||
|
|
||||||
await writeOperation(
|
await writeOperation(
|
||||||
store.put({
|
store.put({
|
||||||
id: guid,
|
id: guid,
|
||||||
@ -112,6 +112,14 @@ export const createIndexedDBProvider = (
|
|||||||
let provider: ReturnType<typeof createLazyProvider> | null = null;
|
let provider: ReturnType<typeof createLazyProvider> | null = null;
|
||||||
|
|
||||||
const apis = {
|
const apis = {
|
||||||
|
get status() {
|
||||||
|
assertExists(provider);
|
||||||
|
return provider.status;
|
||||||
|
},
|
||||||
|
subscribeStatusChange(onStatusChange) {
|
||||||
|
assertExists(provider);
|
||||||
|
return provider.subscribeStatusChange(onStatusChange);
|
||||||
|
},
|
||||||
connect: () => {
|
connect: () => {
|
||||||
if (apis.connected) {
|
if (apis.connected) {
|
||||||
apis.disconnect();
|
apis.disconnect();
|
||||||
@ -132,7 +140,7 @@ export const createIndexedDBProvider = (
|
|||||||
get connected() {
|
get connected() {
|
||||||
return provider?.connected || false;
|
return provider?.connected || false;
|
||||||
},
|
},
|
||||||
};
|
} satisfies IndexedDBProvider;
|
||||||
|
|
||||||
return apis;
|
return apis;
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { StatusAdapter } from '@affine/y-provider';
|
||||||
import type { DBSchema, IDBPDatabase } from 'idb';
|
import type { DBSchema, IDBPDatabase } from 'idb';
|
||||||
|
|
||||||
export const dbVersion = 1;
|
export const dbVersion = 1;
|
||||||
@ -8,7 +9,7 @@ export function upgradeDB(db: IDBPDatabase<BlockSuiteBinaryDB>) {
|
|||||||
db.createObjectStore('milestone', { keyPath: 'id' });
|
db.createObjectStore('milestone', { keyPath: 'id' });
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IndexedDBProvider {
|
export interface IndexedDBProvider extends StatusAdapter {
|
||||||
connect: () => void;
|
connect: () => void;
|
||||||
disconnect: () => void;
|
disconnect: () => void;
|
||||||
cleanup: () => Promise<void>;
|
cleanup: () => Promise<void>;
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
"version": "0.8.0-canary.16",
|
"version": "0.8.0-canary.16",
|
||||||
"description": "Yjs provider utilities for AFFiNE",
|
"description": "Yjs provider utilities for AFFiNE",
|
||||||
"main": "./src/index.ts",
|
"main": "./src/index.ts",
|
||||||
|
"module": "./src/index.ts",
|
||||||
|
"exports": {
|
||||||
|
".": "./src/index.ts"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@blocksuite/store": "0.0.0-20230810005427-25adb757-nightly"
|
"@blocksuite/store": "0.0.0-20230810005427-25adb757-nightly"
|
||||||
},
|
},
|
||||||
|
@ -7,7 +7,8 @@ import {
|
|||||||
encodeStateVectorFromUpdate,
|
encodeStateVectorFromUpdate,
|
||||||
} from 'yjs';
|
} from 'yjs';
|
||||||
|
|
||||||
import type { DatasourceDocAdapter } from './types';
|
import type { DatasourceDocAdapter, StatusAdapter } from './types';
|
||||||
|
import type { Status } from './types';
|
||||||
|
|
||||||
function getDoc(doc: Doc, guid: string): Doc | undefined {
|
function getDoc(doc: Doc, guid: string): Doc | undefined {
|
||||||
if (doc.guid === guid) {
|
if (doc.guid === guid) {
|
||||||
@ -33,7 +34,7 @@ export const createLazyProvider = (
|
|||||||
rootDoc: Doc,
|
rootDoc: Doc,
|
||||||
datasource: DatasourceDocAdapter,
|
datasource: DatasourceDocAdapter,
|
||||||
options: LazyProviderOptions = {}
|
options: LazyProviderOptions = {}
|
||||||
): Omit<PassiveDocProvider, 'flavour'> => {
|
): Omit<PassiveDocProvider, 'flavour'> & StatusAdapter => {
|
||||||
let connected = false;
|
let connected = false;
|
||||||
const pendingMap = new Map<string, Uint8Array[]>(); // guid -> pending-updates
|
const pendingMap = new Map<string, Uint8Array[]>(); // guid -> pending-updates
|
||||||
const disposableMap = new Map<string, Set<() => void>>();
|
const disposableMap = new Map<string, Set<() => void>>();
|
||||||
@ -42,11 +43,59 @@ export const createLazyProvider = (
|
|||||||
|
|
||||||
const { origin = 'lazy-provider' } = options;
|
const { origin = 'lazy-provider' } = options;
|
||||||
|
|
||||||
|
// todo: should we use a real state machine here like `xstate`?
|
||||||
|
let currentStatus: Status = {
|
||||||
|
type: 'idle',
|
||||||
|
};
|
||||||
|
let syncingStack = 0;
|
||||||
|
const callbackSet = new Set<() => void>();
|
||||||
|
const changeStatus = (newStatus: Status) => {
|
||||||
|
// simulate a stack, each syncing and synced should be paired
|
||||||
|
if (newStatus.type === 'idle') {
|
||||||
|
if (syncingStack !== 0) {
|
||||||
|
console.error('syncingStatus !== 0, this should not happen');
|
||||||
|
}
|
||||||
|
syncingStack = 0;
|
||||||
|
}
|
||||||
|
if (newStatus.type === 'syncing') {
|
||||||
|
syncingStack++;
|
||||||
|
}
|
||||||
|
if (newStatus.type === 'synced' || newStatus.type === 'error') {
|
||||||
|
syncingStack--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syncingStack < 0) {
|
||||||
|
console.error('syncingStatus < 0, this should not happen');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syncingStack === 0) {
|
||||||
|
currentStatus = newStatus;
|
||||||
|
}
|
||||||
|
if (newStatus.type !== 'synced') {
|
||||||
|
currentStatus = newStatus;
|
||||||
|
}
|
||||||
|
callbackSet.forEach(cb => cb());
|
||||||
|
};
|
||||||
|
|
||||||
async function syncDoc(doc: Doc) {
|
async function syncDoc(doc: Doc) {
|
||||||
const guid = doc.guid;
|
const guid = doc.guid;
|
||||||
|
|
||||||
const remoteUpdate = await datasource.queryDocState(guid, {
|
changeStatus({
|
||||||
stateVector: encodeStateVector(doc),
|
type: 'syncing',
|
||||||
|
});
|
||||||
|
const remoteUpdate = await datasource
|
||||||
|
.queryDocState(guid, {
|
||||||
|
stateVector: encodeStateVector(doc),
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
changeStatus({
|
||||||
|
type: 'error',
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
changeStatus({
|
||||||
|
type: 'synced',
|
||||||
});
|
});
|
||||||
|
|
||||||
pendingMap.set(guid, []);
|
pendingMap.set(guid, []);
|
||||||
@ -59,6 +108,9 @@ export const createLazyProvider = (
|
|||||||
? encodeStateVectorFromUpdate(remoteUpdate)
|
? encodeStateVectorFromUpdate(remoteUpdate)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
|
if (!connected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// perf: optimize me
|
// perf: optimize me
|
||||||
// it is possible the doc is only in memory but not yet in the datasource
|
// it is possible the doc is only in memory but not yet in the datasource
|
||||||
// we need to send the whole update to the datasource
|
// we need to send the whole update to the datasource
|
||||||
@ -76,7 +128,23 @@ export const createLazyProvider = (
|
|||||||
if (origin === updateOrigin) {
|
if (origin === updateOrigin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
datasource.sendDocUpdate(doc.guid, update).catch(console.error);
|
changeStatus({
|
||||||
|
type: 'syncing',
|
||||||
|
});
|
||||||
|
datasource
|
||||||
|
.sendDocUpdate(doc.guid, update)
|
||||||
|
.then(() => {
|
||||||
|
changeStatus({
|
||||||
|
type: 'synced',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
changeStatus({
|
||||||
|
type: 'error',
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const subdocsHandler = (event: { loaded: Set<Doc>; removed: Set<Doc> }) => {
|
const subdocsHandler = (event: { loaded: Set<Doc>; removed: Set<Doc> }) => {
|
||||||
@ -103,6 +171,9 @@ export const createLazyProvider = (
|
|||||||
*/
|
*/
|
||||||
function setupDatasourceListeners() {
|
function setupDatasourceListeners() {
|
||||||
datasourceUnsub = datasource.onDocUpdate?.((guid, update) => {
|
datasourceUnsub = datasource.onDocUpdate?.((guid, update) => {
|
||||||
|
changeStatus({
|
||||||
|
type: 'syncing',
|
||||||
|
});
|
||||||
const doc = getDoc(rootDoc, guid);
|
const doc = getDoc(rootDoc, guid);
|
||||||
if (doc) {
|
if (doc) {
|
||||||
applyUpdate(doc, update, origin);
|
applyUpdate(doc, update, origin);
|
||||||
@ -120,6 +191,9 @@ export const createLazyProvider = (
|
|||||||
console.warn('idb: doc not found', guid);
|
console.warn('idb: doc not found', guid);
|
||||||
pendingMap.set(guid, (pendingMap.get(guid) ?? []).concat(update));
|
pendingMap.set(guid, (pendingMap.get(guid) ?? []).concat(update));
|
||||||
}
|
}
|
||||||
|
changeStatus({
|
||||||
|
type: 'synced',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,20 +239,44 @@ export const createLazyProvider = (
|
|||||||
function connect() {
|
function connect() {
|
||||||
connected = true;
|
connected = true;
|
||||||
|
|
||||||
|
changeStatus({
|
||||||
|
type: 'syncing',
|
||||||
|
});
|
||||||
// root doc should be already loaded,
|
// root doc should be already loaded,
|
||||||
// but we want to populate the cache for later update events
|
// but we want to populate the cache for later update events
|
||||||
connectDoc(rootDoc).catch(console.error);
|
connectDoc(rootDoc).catch(error => {
|
||||||
|
changeStatus({
|
||||||
|
type: 'error',
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
changeStatus({
|
||||||
|
type: 'synced',
|
||||||
|
});
|
||||||
setupDatasourceListeners();
|
setupDatasourceListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function disconnect() {
|
async function disconnect() {
|
||||||
connected = false;
|
connected = false;
|
||||||
|
changeStatus({
|
||||||
|
type: 'idle',
|
||||||
|
});
|
||||||
disposeAll();
|
disposeAll();
|
||||||
datasourceUnsub?.();
|
datasourceUnsub?.();
|
||||||
datasourceUnsub = undefined;
|
datasourceUnsub = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
get status() {
|
||||||
|
return currentStatus;
|
||||||
|
},
|
||||||
|
subscribeStatusChange(cb: () => void) {
|
||||||
|
callbackSet.add(cb);
|
||||||
|
return () => {
|
||||||
|
callbackSet.delete(cb);
|
||||||
|
};
|
||||||
|
},
|
||||||
get connected() {
|
get connected() {
|
||||||
return connected;
|
return connected;
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,24 @@
|
|||||||
export interface DatasourceDocAdapter {
|
export type Status =
|
||||||
|
| {
|
||||||
|
type: 'idle';
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'syncing';
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'synced';
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'error';
|
||||||
|
error: Error;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface StatusAdapter {
|
||||||
|
readonly status: Status;
|
||||||
|
subscribeStatusChange(onStatusChange: () => void): () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DatasourceDocAdapter extends Partial<StatusAdapter> {
|
||||||
// request diff update from other clients
|
// request diff update from other clients
|
||||||
queryDocState: (
|
queryDocState: (
|
||||||
guid: string,
|
guid: string,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { test } from '@affine-test/kit/playwright';
|
import { test } from '@affine-test/kit/playwright';
|
||||||
import { openHomePage, webUrl } from '@affine-test/kit/utils/load-page';
|
import { coreUrl, openHomePage } from '@affine-test/kit/utils/load-page';
|
||||||
import { waitEditorLoad } from '@affine-test/kit/utils/page-logic';
|
import { waitEditorLoad } from '@affine-test/kit/utils/page-logic';
|
||||||
import { expect } from '@playwright/test';
|
import { expect } from '@playwright/test';
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ test('goto not found workspace', async ({ page }) => {
|
|||||||
await waitEditorLoad(page);
|
await waitEditorLoad(page);
|
||||||
// if doesn't wait for timeout, data won't be saved into indexedDB
|
// if doesn't wait for timeout, data won't be saved into indexedDB
|
||||||
await page.waitForTimeout(1000);
|
await page.waitForTimeout(1000);
|
||||||
await page.goto(new URL('/workspace/invalid/all', webUrl).toString());
|
await page.goto(new URL('/workspace/invalid/all', coreUrl).toString());
|
||||||
await page.waitForTimeout(1000);
|
await page.waitForTimeout(1000);
|
||||||
expect(page.url()).toBe(new URL('/404', webUrl).toString());
|
expect(page.url()).toBe(new URL('/404', coreUrl).toString());
|
||||||
});
|
});
|
||||||
|
12
tests/affine-prototype/e2e/basic.spec.ts
Normal file
12
tests/affine-prototype/e2e/basic.spec.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { test } from '@affine-test/kit/playwright';
|
||||||
|
import { openPrototypeProviderStatusPage } from '@affine-test/kit/utils/load-page';
|
||||||
|
import { expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test('syncing and synced status should works', async ({ page }) => {
|
||||||
|
await openPrototypeProviderStatusPage(page);
|
||||||
|
await expect(page.getByTestId('status')).toHaveText('synced');
|
||||||
|
await page.getByTestId('start-button').click();
|
||||||
|
await expect(page.getByTestId('status')).toHaveText('syncing');
|
||||||
|
await page.getByTestId('stop-button').click();
|
||||||
|
await expect(page.getByTestId('status')).toHaveText('synced');
|
||||||
|
});
|
13
tests/affine-prototype/package.json
Normal file
13
tests/affine-prototype/package.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "@affine-test/affine-prototype",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"e2e": "yarn playwright test"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@affine-test/fixtures": "workspace:*",
|
||||||
|
"@affine-test/kit": "workspace:*",
|
||||||
|
"@playwright/test": "^1.36.2"
|
||||||
|
},
|
||||||
|
"version": "0.8.0-canary.14"
|
||||||
|
}
|
63
tests/affine-prototype/playwright.config.ts
Normal file
63
tests/affine-prototype/playwright.config.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import type {
|
||||||
|
PlaywrightTestConfig,
|
||||||
|
PlaywrightWorkerOptions,
|
||||||
|
} from '@playwright/test';
|
||||||
|
// import { devices } from '@playwright/test';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read environment variables from file.
|
||||||
|
* https://github.com/motdotla/dotenv
|
||||||
|
*/
|
||||||
|
// require('dotenv').config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See https://playwright.dev/docs/test-configuration.
|
||||||
|
*/
|
||||||
|
const config: PlaywrightTestConfig = {
|
||||||
|
testDir: './e2e',
|
||||||
|
fullyParallel: true,
|
||||||
|
timeout: process.env.CI ? 50_000 : 30_000,
|
||||||
|
use: {
|
||||||
|
baseURL: 'http://localhost:8080/',
|
||||||
|
browserName:
|
||||||
|
(process.env.BROWSER as PlaywrightWorkerOptions['browserName']) ??
|
||||||
|
'chromium',
|
||||||
|
permissions: ['clipboard-read', 'clipboard-write'],
|
||||||
|
viewport: { width: 1440, height: 800 },
|
||||||
|
actionTimeout: 5 * 1000,
|
||||||
|
locale: 'en-US',
|
||||||
|
// Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer
|
||||||
|
// You can open traces locally(`npx playwright show-trace trace.zip`)
|
||||||
|
// or in your browser on [Playwright Trace Viewer](https://trace.playwright.dev/).
|
||||||
|
trace: 'on-first-retry',
|
||||||
|
// Record video only when retrying a test for the first time.
|
||||||
|
video: 'on-first-retry',
|
||||||
|
},
|
||||||
|
forbidOnly: !!process.env.CI,
|
||||||
|
workers: 4,
|
||||||
|
retries: 1,
|
||||||
|
// 'github' for GitHub Actions CI to generate annotations, plus a concise 'dot'
|
||||||
|
// default 'list' when running locally
|
||||||
|
// See https://playwright.dev/docs/test-reporters#github-actions-annotations
|
||||||
|
reporter: process.env.CI ? 'github' : 'list',
|
||||||
|
|
||||||
|
webServer: [
|
||||||
|
// Intentionally not building the web, reminds you to run it by yourself.
|
||||||
|
{
|
||||||
|
command: 'yarn workspace @affine/prototype preview',
|
||||||
|
port: 3003,
|
||||||
|
timeout: 120 * 1000,
|
||||||
|
reuseExistingServer: !process.env.CI,
|
||||||
|
env: {
|
||||||
|
COVERAGE: process.env.COVERAGE || 'false',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (process.env.CI) {
|
||||||
|
config.retries = 3;
|
||||||
|
config.workers = '50%';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config;
|
16
tests/affine-prototype/tsconfig.json
Normal file
16
tests/affine-prototype/tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"outDir": "lib"
|
||||||
|
},
|
||||||
|
"include": ["e2e"],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "../kit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../fixtures"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,11 +1,16 @@
|
|||||||
import type { Page } from '@playwright/test';
|
import type { Page } from '@playwright/test';
|
||||||
|
|
||||||
export const webUrl = 'http://localhost:8080';
|
export const coreUrl = 'http://localhost:8080';
|
||||||
|
export const prototypeUrl = 'http://localhost:3003';
|
||||||
|
|
||||||
export async function openHomePage(page: Page) {
|
export async function openHomePage(page: Page) {
|
||||||
await page.goto(webUrl);
|
await page.goto(coreUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function openPluginPage(page: Page) {
|
export async function openPluginPage(page: Page) {
|
||||||
await page.goto(`${webUrl}/_plugin/index.html`);
|
await page.goto(`${coreUrl}/_plugin/index.html`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function openPrototypeProviderStatusPage(page: Page) {
|
||||||
|
await page.goto(`${prototypeUrl}/suite/provider-status.html`);
|
||||||
}
|
}
|
||||||
|
@ -169,8 +169,14 @@
|
|||||||
{
|
{
|
||||||
"path": "./tests/affine-plugin"
|
"path": "./tests/affine-plugin"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "./tests/affine-prototype"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "./tests/affine-legacy/0.7.0-canary.18"
|
"path": "./tests/affine-legacy/0.7.0-canary.18"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tests/affine-legacy/0.8.0-canary.7"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"files": [],
|
"files": [],
|
||||||
|
211
yarn.lock
211
yarn.lock
@ -73,6 +73,16 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
"@affine-test/affine-prototype@workspace:tests/affine-prototype":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "@affine-test/affine-prototype@workspace:tests/affine-prototype"
|
||||||
|
dependencies:
|
||||||
|
"@affine-test/fixtures": "workspace:*"
|
||||||
|
"@affine-test/kit": "workspace:*"
|
||||||
|
"@playwright/test": ^1.36.2
|
||||||
|
languageName: unknown
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"@affine-test/fixtures@workspace:*, @affine-test/fixtures@workspace:tests/fixtures":
|
"@affine-test/fixtures@workspace:*, @affine-test/fixtures@workspace:tests/fixtures":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@affine-test/fixtures@workspace:tests/fixtures"
|
resolution: "@affine-test/fixtures@workspace:tests/fixtures"
|
||||||
@ -558,6 +568,38 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
"@affine/prototype@workspace:apps/prototype":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "@affine/prototype@workspace:apps/prototype"
|
||||||
|
dependencies:
|
||||||
|
"@affine-test/fixtures": "workspace:*"
|
||||||
|
"@affine/component": "workspace:*"
|
||||||
|
"@affine/debug": "workspace:*"
|
||||||
|
"@affine/env": "workspace:*"
|
||||||
|
"@affine/graphql": "workspace:*"
|
||||||
|
"@affine/i18n": "workspace:*"
|
||||||
|
"@affine/jotai": "workspace:*"
|
||||||
|
"@affine/templates": "workspace:*"
|
||||||
|
"@affine/workspace": "workspace:*"
|
||||||
|
"@blocksuite/block-std": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/blocks": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/editor": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/global": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/icons": ^2.1.31
|
||||||
|
"@blocksuite/lit": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/store": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@toeverything/hooks": "workspace:*"
|
||||||
|
"@toeverything/y-indexeddb": "workspace:*"
|
||||||
|
"@types/react": ^18.2.20
|
||||||
|
"@types/react-dom": ^18.2.7
|
||||||
|
"@vitejs/plugin-react-swc": ^3.3.2
|
||||||
|
react: ^18.2.0
|
||||||
|
react-dom: ^18.2.0
|
||||||
|
typescript: ^5.1.6
|
||||||
|
vite: ^4.4.9
|
||||||
|
languageName: unknown
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"@affine/sdk@workspace:*, @affine/sdk@workspace:packages/sdk":
|
"@affine/sdk@workspace:*, @affine/sdk@workspace:packages/sdk":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@affine/sdk@workspace:packages/sdk"
|
resolution: "@affine/sdk@workspace:packages/sdk"
|
||||||
@ -3349,6 +3391,18 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@blocksuite/block-std@npm:0.0.0-20230809030546-32e6e21d-nightly":
|
||||||
|
version: 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
resolution: "@blocksuite/block-std@npm:0.0.0-20230809030546-32e6e21d-nightly"
|
||||||
|
dependencies:
|
||||||
|
"@blocksuite/global": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
w3c-keyname: ^2.2.8
|
||||||
|
peerDependencies:
|
||||||
|
"@blocksuite/store": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
checksum: 728387fe20e4b3534d6723172479b9116621a1398c9f28b4ef4e008d028717ba960e3a6d59508a45f07cfff43c71175466c10f71d48a0062938a16de2d3462c6
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/block-std@npm:0.0.0-20230810005427-25adb757-nightly":
|
"@blocksuite/block-std@npm:0.0.0-20230810005427-25adb757-nightly":
|
||||||
version: 0.0.0-20230810005427-25adb757-nightly
|
version: 0.0.0-20230810005427-25adb757-nightly
|
||||||
resolution: "@blocksuite/block-std@npm:0.0.0-20230810005427-25adb757-nightly"
|
resolution: "@blocksuite/block-std@npm:0.0.0-20230810005427-25adb757-nightly"
|
||||||
@ -3361,6 +3415,34 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@blocksuite/blocks@npm:0.0.0-20230809030546-32e6e21d-nightly":
|
||||||
|
version: 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
resolution: "@blocksuite/blocks@npm:0.0.0-20230809030546-32e6e21d-nightly"
|
||||||
|
dependencies:
|
||||||
|
"@blocksuite/global": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/phasor": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/virgo": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@floating-ui/dom": ^1.5.1
|
||||||
|
buffer: ^6.0.3
|
||||||
|
date-fns: ^2.30.0
|
||||||
|
file-type: ^16.5.4
|
||||||
|
html2canvas: ^1.4.1
|
||||||
|
jszip: ^3.10.1
|
||||||
|
lit: ^2.7.6
|
||||||
|
marked: ^4.3.0
|
||||||
|
pdf-lib: ^1.17.1
|
||||||
|
shiki: ^0.14.3
|
||||||
|
turndown: ^7.1.2
|
||||||
|
zod: ^3.21.4
|
||||||
|
peerDependencies:
|
||||||
|
"@blocksuite/block-std": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/lit": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/store": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
yjs: ^13
|
||||||
|
checksum: 8f4f4942541b6c0efd5b6527e906dfba36fb7a1b9ef32042bcfa3cbadcf0da3f55bd8f22edade27b630c62290483a1d464b300edf7406ade909aaf41e3c88b5b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/blocks@npm:0.0.0-20230810005427-25adb757-nightly":
|
"@blocksuite/blocks@npm:0.0.0-20230810005427-25adb757-nightly":
|
||||||
version: 0.0.0-20230810005427-25adb757-nightly
|
version: 0.0.0-20230810005427-25adb757-nightly
|
||||||
resolution: "@blocksuite/blocks@npm:0.0.0-20230810005427-25adb757-nightly"
|
resolution: "@blocksuite/blocks@npm:0.0.0-20230810005427-25adb757-nightly"
|
||||||
@ -3390,6 +3472,23 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@blocksuite/editor@npm:0.0.0-20230809030546-32e6e21d-nightly":
|
||||||
|
version: 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
resolution: "@blocksuite/editor@npm:0.0.0-20230809030546-32e6e21d-nightly"
|
||||||
|
dependencies:
|
||||||
|
"@blocksuite/global": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
lit: ^2.7.6
|
||||||
|
marked: ^4.3.0
|
||||||
|
turndown: ^7.1.2
|
||||||
|
peerDependencies:
|
||||||
|
"@blocksuite/blocks": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/lit": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/store": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@toeverything/theme": ^0.7.9
|
||||||
|
checksum: e01ae29d424f1273a5c0ab9f969baad4b58ad8510255df4ea03addab06e12203d51edef87a36fcc20a05233d3863418540b6846229b8dd4fed1d295ce5abef78
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/editor@npm:0.0.0-20230810005427-25adb757-nightly":
|
"@blocksuite/editor@npm:0.0.0-20230810005427-25adb757-nightly":
|
||||||
version: 0.0.0-20230810005427-25adb757-nightly
|
version: 0.0.0-20230810005427-25adb757-nightly
|
||||||
resolution: "@blocksuite/editor@npm:0.0.0-20230810005427-25adb757-nightly"
|
resolution: "@blocksuite/editor@npm:0.0.0-20230810005427-25adb757-nightly"
|
||||||
@ -3405,6 +3504,21 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@blocksuite/global@npm:0.0.0-20230809030546-32e6e21d-nightly":
|
||||||
|
version: 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
resolution: "@blocksuite/global@npm:0.0.0-20230809030546-32e6e21d-nightly"
|
||||||
|
dependencies:
|
||||||
|
ansi-colors: ^4.1.3
|
||||||
|
zod: ^3.21.4
|
||||||
|
peerDependencies:
|
||||||
|
lit: ^2.7
|
||||||
|
peerDependenciesMeta:
|
||||||
|
lit:
|
||||||
|
optional: true
|
||||||
|
checksum: 03eb2fe544f4122f0b4369c637de0238cf8e6731ac7d47e9890a401da5ee20a21bb93c1fdd306f4379bdd5c7956b861fcad8b279145cdf370f009314a6feed72
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/global@npm:0.0.0-20230810005427-25adb757-nightly":
|
"@blocksuite/global@npm:0.0.0-20230810005427-25adb757-nightly":
|
||||||
version: 0.0.0-20230810005427-25adb757-nightly
|
version: 0.0.0-20230810005427-25adb757-nightly
|
||||||
resolution: "@blocksuite/global@npm:0.0.0-20230810005427-25adb757-nightly"
|
resolution: "@blocksuite/global@npm:0.0.0-20230810005427-25adb757-nightly"
|
||||||
@ -3440,6 +3554,19 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@blocksuite/lit@npm:0.0.0-20230809030546-32e6e21d-nightly":
|
||||||
|
version: 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
resolution: "@blocksuite/lit@npm:0.0.0-20230809030546-32e6e21d-nightly"
|
||||||
|
dependencies:
|
||||||
|
"@blocksuite/global": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
lit: ^2.7.6
|
||||||
|
peerDependencies:
|
||||||
|
"@blocksuite/block-std": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/store": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
checksum: c8ba7e600839fe463368d804f26fd6c369f22693681cd9c7f94500988c2a83054ef156e56e71621f1b6a67e2667703ff657d4f10e98de52f3b616ec285ee8a0c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/lit@npm:0.0.0-20230810005427-25adb757-nightly":
|
"@blocksuite/lit@npm:0.0.0-20230810005427-25adb757-nightly":
|
||||||
version: 0.0.0-20230810005427-25adb757-nightly
|
version: 0.0.0-20230810005427-25adb757-nightly
|
||||||
resolution: "@blocksuite/lit@npm:0.0.0-20230810005427-25adb757-nightly"
|
resolution: "@blocksuite/lit@npm:0.0.0-20230810005427-25adb757-nightly"
|
||||||
@ -3453,6 +3580,19 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@blocksuite/phasor@npm:0.0.0-20230809030546-32e6e21d-nightly":
|
||||||
|
version: 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
resolution: "@blocksuite/phasor@npm:0.0.0-20230809030546-32e6e21d-nightly"
|
||||||
|
dependencies:
|
||||||
|
"@blocksuite/global": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
fractional-indexing: ^3.2.0
|
||||||
|
peerDependencies:
|
||||||
|
nanoid: ^4
|
||||||
|
yjs: ^13
|
||||||
|
checksum: 46ee3d98ed054df635db30eccb716495c313ab341e4d471ae23912c855fa7c946c4b830294e93d6a7435b2c65fb1e7bdba53cf61c24cc85b13d14f50cabb9f1d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/phasor@npm:0.0.0-20230810005427-25adb757-nightly":
|
"@blocksuite/phasor@npm:0.0.0-20230810005427-25adb757-nightly":
|
||||||
version: 0.0.0-20230810005427-25adb757-nightly
|
version: 0.0.0-20230810005427-25adb757-nightly
|
||||||
resolution: "@blocksuite/phasor@npm:0.0.0-20230810005427-25adb757-nightly"
|
resolution: "@blocksuite/phasor@npm:0.0.0-20230810005427-25adb757-nightly"
|
||||||
@ -3466,6 +3606,30 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@blocksuite/store@npm:0.0.0-20230809030546-32e6e21d-nightly":
|
||||||
|
version: 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
resolution: "@blocksuite/store@npm:0.0.0-20230809030546-32e6e21d-nightly"
|
||||||
|
dependencies:
|
||||||
|
"@blocksuite/global": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
"@blocksuite/virgo": 0.0.0-20230809030546-32e6e21d-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
|
||||||
|
merge: ^2.1.1
|
||||||
|
minimatch: ^9.0.3
|
||||||
|
nanoid: ^4.0.2
|
||||||
|
y-protocols: ^1.0.5
|
||||||
|
zod: ^3.21.4
|
||||||
|
peerDependencies:
|
||||||
|
async-call-rpc: ^6
|
||||||
|
yjs: ^13
|
||||||
|
checksum: 262b0858917f05eafba6c440bf7b5310e2509c1df44c67c6cc32b417af906970b1073a2864fa3c494dd993e7b6da7b16a975dbb31a240767b8e0963dd6334b3d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/store@npm:0.0.0-20230810005427-25adb757-nightly":
|
"@blocksuite/store@npm:0.0.0-20230810005427-25adb757-nightly":
|
||||||
version: 0.0.0-20230810005427-25adb757-nightly
|
version: 0.0.0-20230810005427-25adb757-nightly
|
||||||
resolution: "@blocksuite/store@npm:0.0.0-20230810005427-25adb757-nightly"
|
resolution: "@blocksuite/store@npm:0.0.0-20230810005427-25adb757-nightly"
|
||||||
@ -3490,6 +3654,19 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@blocksuite/virgo@npm:0.0.0-20230809030546-32e6e21d-nightly":
|
||||||
|
version: 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
resolution: "@blocksuite/virgo@npm:0.0.0-20230809030546-32e6e21d-nightly"
|
||||||
|
dependencies:
|
||||||
|
"@blocksuite/global": 0.0.0-20230809030546-32e6e21d-nightly
|
||||||
|
zod: ^3.21.4
|
||||||
|
peerDependencies:
|
||||||
|
lit: ^2.7
|
||||||
|
yjs: ^13
|
||||||
|
checksum: b870ef551a856e44eca743962c8b25d97e80aece9a0172c983b34ab7bb8cc4a2d3f8fa93d1550b0d2e500cf409a72aa8e72a415ccbb791598c4c8354cec1389e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/virgo@npm:0.0.0-20230810005427-25adb757-nightly":
|
"@blocksuite/virgo@npm:0.0.0-20230810005427-25adb757-nightly":
|
||||||
version: 0.0.0-20230810005427-25adb757-nightly
|
version: 0.0.0-20230810005427-25adb757-nightly
|
||||||
resolution: "@blocksuite/virgo@npm:0.0.0-20230810005427-25adb757-nightly"
|
resolution: "@blocksuite/virgo@npm:0.0.0-20230810005427-25adb757-nightly"
|
||||||
@ -11307,20 +11484,39 @@ __metadata:
|
|||||||
resolution: "@toeverything/hooks@workspace:packages/hooks"
|
resolution: "@toeverything/hooks@workspace:packages/hooks"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@affine/env": "workspace:*"
|
"@affine/env": "workspace:*"
|
||||||
|
"@affine/y-provider": "workspace:*"
|
||||||
"@blocksuite/block-std": 0.0.0-20230810005427-25adb757-nightly
|
"@blocksuite/block-std": 0.0.0-20230810005427-25adb757-nightly
|
||||||
"@blocksuite/blocks": 0.0.0-20230810005427-25adb757-nightly
|
"@blocksuite/blocks": 0.0.0-20230810005427-25adb757-nightly
|
||||||
"@blocksuite/editor": 0.0.0-20230810005427-25adb757-nightly
|
"@blocksuite/editor": 0.0.0-20230810005427-25adb757-nightly
|
||||||
"@blocksuite/global": 0.0.0-20230810005427-25adb757-nightly
|
"@blocksuite/global": 0.0.0-20230810005427-25adb757-nightly
|
||||||
"@blocksuite/lit": 0.0.0-20230810005427-25adb757-nightly
|
"@blocksuite/lit": 0.0.0-20230810005427-25adb757-nightly
|
||||||
"@blocksuite/store": 0.0.0-20230810005427-25adb757-nightly
|
"@blocksuite/store": 0.0.0-20230810005427-25adb757-nightly
|
||||||
"@toeverything/y-indexeddb": "workspace:*"
|
foxact: ^0.2.17
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
"@affine/y-provider": "workspace:*"
|
||||||
"@blocksuite/block-std": "*"
|
"@blocksuite/block-std": "*"
|
||||||
"@blocksuite/blocks": "*"
|
"@blocksuite/blocks": "*"
|
||||||
"@blocksuite/editor": "*"
|
"@blocksuite/editor": "*"
|
||||||
"@blocksuite/global": "*"
|
"@blocksuite/global": "*"
|
||||||
"@blocksuite/lit": "*"
|
"@blocksuite/lit": "*"
|
||||||
"@blocksuite/store": "*"
|
"@blocksuite/store": "*"
|
||||||
|
peerDependenciesMeta:
|
||||||
|
"@affine/env":
|
||||||
|
optional: true
|
||||||
|
"@affine/y-provider":
|
||||||
|
optional: true
|
||||||
|
"@blocksuite/block-std":
|
||||||
|
optional: true
|
||||||
|
"@blocksuite/blocks":
|
||||||
|
optional: true
|
||||||
|
"@blocksuite/editor":
|
||||||
|
optional: true
|
||||||
|
"@blocksuite/global":
|
||||||
|
optional: true
|
||||||
|
"@blocksuite/lit":
|
||||||
|
optional: true
|
||||||
|
"@blocksuite/store":
|
||||||
|
optional: true
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@ -12141,6 +12337,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/react@npm:^18.2.20":
|
||||||
|
version: 18.2.20
|
||||||
|
resolution: "@types/react@npm:18.2.20"
|
||||||
|
dependencies:
|
||||||
|
"@types/prop-types": "*"
|
||||||
|
"@types/scheduler": "*"
|
||||||
|
csstype: ^3.0.2
|
||||||
|
checksum: 30f699c60e5e4bfef273ce64d320651cdd60f5c6a08361c6c7eca8cebcccda1ac953d2ee57c9f321b5ae87f8a62c72b6d35ca42df0e261d337849952daab2141
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/responselike@npm:^1.0.0":
|
"@types/responselike@npm:^1.0.0":
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
resolution: "@types/responselike@npm:1.0.0"
|
resolution: "@types/responselike@npm:1.0.0"
|
||||||
@ -27533,7 +27740,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"react-dom@npm:18.2.0":
|
"react-dom@npm:18.2.0, react-dom@npm:^18.2.0":
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
resolution: "react-dom@npm:18.2.0"
|
resolution: "react-dom@npm:18.2.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
Reference in New Issue
Block a user