diff --git a/.github/actions/download-core/action.yml b/.github/actions/download-web/action.yml similarity index 96% rename from .github/actions/download-core/action.yml rename to .github/actions/download-web/action.yml index 2746bd845..b5ea42e6d 100644 --- a/.github/actions/download-core/action.yml +++ b/.github/actions/download-web/action.yml @@ -11,7 +11,7 @@ runs: - name: Download tar.gz uses: actions/download-artifact@v4 with: - name: core + name: web path: . - name: Extract core artifacts diff --git a/.github/deployment/front/Dockerfile b/.github/deployment/front/Dockerfile index 3c3a58fd9..81030c7aa 100644 --- a/.github/deployment/front/Dockerfile +++ b/.github/deployment/front/Dockerfile @@ -1,6 +1,6 @@ FROM openresty/openresty:1.25.3.1-0-buster WORKDIR /app -COPY ./packages/frontend/core/dist ./dist +COPY ./packages/frontend/web/dist ./dist COPY ./.github/deployment/front/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf COPY ./.github/deployment/front/affine.nginx.conf /etc/nginx/conf.d/affine.nginx.conf diff --git a/.github/deployment/node/Dockerfile b/.github/deployment/node/Dockerfile index 50e370700..716431210 100644 --- a/.github/deployment/node/Dockerfile +++ b/.github/deployment/node/Dockerfile @@ -1,7 +1,7 @@ FROM node:20-bookworm-slim COPY ./packages/backend/server /app -COPY ./packages/frontend/core/dist /app/static +COPY ./packages/frontend/web/dist /app/static WORKDIR /app RUN apt-get update && \ diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 6de163706..ca42ded39 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -266,8 +266,8 @@ jobs: path: ./packages/backend/storage/storage.node if-no-files-found: error - build-core: - name: Build @affine/core + build-web: + name: Build @affine/web runs-on: ubuntu-latest steps: @@ -277,15 +277,15 @@ jobs: with: electron-install: false full-cache: true - - name: Build Core + - name: Build Web # always skip cache because its fast, and cache configuration is always changing - run: yarn nx build @affine/core --skip-nx-cache - - name: zip core - run: tar -czf dist.tar.gz --directory=packages/frontend/core/dist . - - name: Upload core artifact + run: yarn nx build @affine/web --skip-nx-cache + - name: zip web + run: tar -czf dist.tar.gz --directory=packages/frontend/web/dist . + - name: Upload web artifact uses: actions/upload-artifact@v4 with: - name: core + name: web path: dist.tar.gz if-no-files-found: error @@ -485,7 +485,7 @@ jobs: test: true, } needs: - - build-core + - build-web - build-native steps: - uses: actions/checkout@v4 @@ -516,8 +516,8 @@ jobs: shell: bash run: yarn workspace @affine/electron vitest - - name: Download core artifact - uses: ./.github/actions/download-core + - name: Download web artifact + uses: ./.github/actions/download-web with: path: packages/frontend/electron/resources/web-static diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4a534fa63..96c23fe6b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -38,8 +38,8 @@ jobs: name: server-dist path: ./packages/backend/server/dist if-no-files-found: error - build-core: - name: Build @affine/core + build-web: + name: Build @affine/web runs-on: ubuntu-latest environment: ${{ github.event.inputs.flavor }} steps: @@ -50,7 +50,7 @@ jobs: - name: Setup Node.js uses: ./.github/actions/setup-node - name: Build Core - run: yarn nx build @affine/core --skip-nx-cache + run: yarn nx build @affine/web --skip-nx-cache env: R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} @@ -64,15 +64,15 @@ jobs: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} PERFSEE_TOKEN: ${{ secrets.PERFSEE_TOKEN }} - - name: Upload core artifact + - name: Upload web artifact uses: actions/upload-artifact@v4 with: - name: core - path: ./packages/frontend/core/dist + name: web + path: ./packages/frontend/web/dist if-no-files-found: error - build-core-selfhost: - name: Build @affine/core selfhost + build-web-selfhost: + name: Build @affine/web selfhost runs-on: ubuntu-latest environment: ${{ github.event.inputs.flavor }} steps: @@ -83,7 +83,7 @@ jobs: - name: Setup Node.js uses: ./.github/actions/setup-node - name: Build Core - run: yarn nx build @affine/core --skip-nx-cache + run: yarn nx build @affine/web --skip-nx-cache env: BUILD_TYPE: ${{ github.event.inputs.flavor }} SHOULD_REPORT_TRACE: false @@ -91,11 +91,11 @@ jobs: SELF_HOSTED: true - name: Download selfhost fonts run: node ./scripts/download-blocksuite-fonts.mjs - - name: Upload core artifact + - name: Upload web artifact uses: actions/upload-artifact@v4 with: - name: selfhost-core - path: ./packages/frontend/core/dist + name: selfhost-web + path: ./packages/frontend/web/dist if-no-files-found: error build-storage: @@ -143,16 +143,16 @@ jobs: packages: 'write' needs: - build-server - - build-core - - build-core-selfhost + - build-web + - build-web-selfhost - build-storage steps: - uses: actions/checkout@v4 - name: Download core artifact uses: actions/download-artifact@v4 with: - name: core - path: ./packages/frontend/core/dist + name: web + path: ./packages/frontend/web/dist - name: Download server dist uses: actions/download-artifact@v4 with: @@ -218,14 +218,14 @@ jobs: registry-url: https://npm.pkg.github.com scope: '@toeverything' - - name: Remove core dist - run: rm -rf ./packages/frontend/core/dist + - name: Remove web dist + run: rm -rf ./packages/frontend/web/dist - - name: Download selfhost core artifact + - name: Download selfhost web artifact uses: actions/download-artifact@v4 with: - name: selfhost-core - path: ./packages/frontend/core/dist + name: selfhost-web + path: ./packages/frontend/web/dist - name: Install Node.js dependencies run: | diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index f514dd495..95a12a9a5 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -60,10 +60,10 @@ jobs: SKIP_PLUGIN_BUILD: 'true' SKIP_NX_CACHE: 'true' - - name: Upload core artifact + - name: Upload web artifact uses: actions/upload-artifact@v4 with: - name: core + name: web path: packages/frontend/electron/resources/web-static make-distribution: @@ -110,7 +110,7 @@ jobs: nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} - uses: actions/download-artifact@v4 with: - name: core + name: web path: packages/frontend/electron/resources/web-static - name: Build Desktop Layers @@ -188,7 +188,7 @@ jobs: nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} - uses: actions/download-artifact@v4 with: - name: core + name: web path: packages/frontend/electron/resources/web-static - name: Build Desktop Layers @@ -317,7 +317,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: - name: core + name: web path: web-static - name: Zip web-static run: zip -r web-static.zip web-static diff --git a/package.json b/package.json index 5cf48ea74..f966d6d22 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,13 @@ "node": "<21.0.0" }, "scripts": { - "dev": "dev-core", + "dev": "yarn workspace @affine/cli dev", "dev:electron": "yarn workspace @affine/electron dev", - "build": "yarn nx build @affine/core", + "build": "yarn nx build @affine/web", "build:electron": "yarn nx build @affine/electron", "build:storage": "yarn nx run-many -t build -p @affine/storage", "build:storybook": "yarn nx build @affine/storybook", - "start:web-static": "yarn workspace @affine/core static-server", + "start:web-static": "yarn workspace @affine/web static-server", "start:storybook": "yarn exec serve tests/storybook/storybook-static -l 6006", "serve:test-static": "yarn exec serve tests/fixtures --cors -p 8081", "lint:eslint": "eslint . --ext .js,mjs,.ts,.tsx --cache", diff --git a/packages/backend/server/package.json b/packages/backend/server/package.json index 180b48c28..67db8461b 100644 --- a/packages/backend/server/package.json +++ b/packages/backend/server/package.json @@ -20,7 +20,7 @@ "dependencies": { "@apollo/server": "^4.10.0", "@auth/prisma-adapter": "^1.4.0", - "@aws-sdk/client-s3": "^3.515.0", + "@aws-sdk/client-s3": "^3.536.0", "@google-cloud/opentelemetry-cloud-monitoring-exporter": "^0.17.0", "@google-cloud/opentelemetry-cloud-trace-exporter": "^2.1.0", "@google-cloud/opentelemetry-resource-util": "^2.1.0", diff --git a/packages/common/env/src/global.ts b/packages/common/env/src/global.ts index e40c78380..fb329ac6a 100644 --- a/packages/common/env/src/global.ts +++ b/packages/common/env/src/global.ts @@ -19,7 +19,6 @@ export const runtimeFlagsSchema = z.object({ enableNewSettingModal: z.boolean(), enableNewSettingUnstableApi: z.boolean(), enableSQLiteProvider: z.boolean(), - enableNotificationCenter: z.boolean(), enableCloud: z.boolean(), enableCaptcha: z.boolean(), enableEnhanceShareMode: z.boolean(), diff --git a/packages/frontend/component/.storybook/main.ts b/packages/frontend/component/.storybook/main.ts index 69fea0e0e..85ee4598c 100644 --- a/packages/frontend/component/.storybook/main.ts +++ b/packages/frontend/component/.storybook/main.ts @@ -1,8 +1,7 @@ import { StorybookConfig } from '@storybook/react-vite'; import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; -import { fileURLToPath } from 'url'; import { mergeConfig } from 'vite'; -import { getRuntimeConfig } from '../../core/.webpack/runtime-config'; +import { getRuntimeConfig } from '@affine/cli/src/webpack/runtime-config'; export default { stories: ['../src/ui/**/*.stories.@(js|jsx|ts|tsx|mdx)'], diff --git a/packages/frontend/component/package.json b/packages/frontend/component/package.json index 14a3af81f..e0e7a475a 100644 --- a/packages/frontend/component/package.json +++ b/packages/frontend/component/package.json @@ -20,6 +20,7 @@ "@blocksuite/store": "*" }, "dependencies": { + "@affine/cli": "workspace:*", "@affine/debug": "workspace:*", "@affine/electron-api": "workspace:*", "@affine/graphql": "workspace:*", diff --git a/packages/frontend/core/package.json b/packages/frontend/core/package.json index d330e3aae..529bbd65b 100644 --- a/packages/frontend/core/package.json +++ b/packages/frontend/core/package.json @@ -3,14 +3,9 @@ "type": "module", "private": true, "version": "0.14.0", - "scripts": { - "build": "yarn -T run build-core", - "dev": "yarn -T run dev-core", - "static-server": "yarn -T run dev-core --static" - }, "exports": { "./app": "./src/app.tsx", - "./router": "./src/router.ts", + "./router": "./src/router.tsx", "./bootstrap/setup": "./src/bootstrap/setup.ts", "./bootstrap/register-plugins": "./src/bootstrap/register-plugins.ts", "./*": "./src/*" @@ -40,7 +35,6 @@ "@emotion/react": "^11.11.3", "@emotion/server": "^11.11.0", "@emotion/styled": "^11.11.0", - "@juggle/resize-observer": "^3.4.0", "@marsidev/react-turnstile": "^0.5.3", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", @@ -59,7 +53,6 @@ "clsx": "^2.1.0", "cmdk": "patch:cmdk@npm%3A0.2.0#~/.yarn/patches/cmdk-npm-0.2.0-302237a911.patch", "css-spring": "^4.1.0", - "cssnano": "^6.0.4", "dayjs": "^1.11.10", "foxact": "^0.2.31", "fractional-indexing": "^3.2.0", @@ -67,7 +60,6 @@ "history": "^5.3.0", "idb": "^8.0.0", "image-blob-reduce": "^4.1.0", - "intl-segmenter-polyfill-rs": "^0.1.7", "jotai": "^2.6.5", "jotai-devtools": "^0.8.0", "jotai-effect": "^0.6.0", @@ -76,10 +68,8 @@ "lodash-es": "^4.17.21", "lottie-react": "^2.4.0", "lottie-web": "^5.12.2", - "mini-css-extract-plugin": "^2.8.0", "nanoid": "^5.0.6", "next-themes": "^0.3.0", - "postcss-loader": "^8.1.0", "react": "18.2.0", "react-dom": "18.2.0", "react-error-boundary": "^4.0.12", @@ -108,24 +98,11 @@ "@types/image-blob-reduce": "^4.1.4", "@types/lodash-es": "^4.17.12", "@types/uuid": "^9.0.8", - "@types/webpack-env": "^1.18.4", "@vanilla-extract/css": "^1.14.1", - "copy-webpack-plugin": "^12.0.2", - "css-loader": "^6.10.0", "express": "^4.18.2", "fake-indexeddb": "^5.0.2", - "html-webpack-plugin": "^5.6.0", "lodash-es": "^4.17.21", "mime-types": "^2.1.35", - "raw-loader": "^4.0.2", - "source-map-loader": "^5.0.0", - "style-loader": "^3.3.4", - "swc-loader": "^0.2.6", - "thread-loader": "^4.0.2", - "vitest": "1.4.0", - "webpack": "^5.90.3", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.0.2", - "webpack-merge": "^5.10.0" + "vitest": "1.4.0" } } diff --git a/packages/frontend/core/src/hooks/use-app-config-storage.ts b/packages/frontend/core/src/hooks/use-app-config-storage.ts index 6430a9b6d..0d7f3b5a8 100644 --- a/packages/frontend/core/src/hooks/use-app-config-storage.ts +++ b/packages/frontend/core/src/hooks/use-app-config-storage.ts @@ -1,4 +1,5 @@ import { apis } from '@affine/electron-api'; +import { setupGlobal } from '@affine/env/global'; import { assertExists } from '@blocksuite/global/utils'; import { type AppConfigSchema, @@ -35,6 +36,8 @@ class AppConfigProxy { } export const appConfigProxy = new AppConfigProxy(); +setupGlobal(); + const storage = environment.isDesktop ? new AppConfigStorage({ config: defaultAppConfig, diff --git a/packages/frontend/core/src/index.tsx b/packages/frontend/core/src/index.tsx index 413dfe651..b80c83af3 100644 --- a/packages/frontend/core/src/index.tsx +++ b/packages/frontend/core/src/index.tsx @@ -1,43 +1 @@ -import './polyfill/intl-segmenter'; -import './polyfill/request-idle-callback'; -import './polyfill/resize-observer'; - -import { assertExists } from '@blocksuite/global/utils'; -import { StrictMode } from 'react'; -import { createRoot } from 'react-dom/client'; - -import { App } from './app'; -import { setup } from './bootstrap/setup'; -import { performanceLogger } from './shared'; - -const performanceMainLogger = performanceLogger.namespace('main'); -function main() { - performanceMainLogger.info('start'); - - // skip bootstrap setup for desktop onboarding - if (window.appInfo?.windowName !== 'onboarding') { - performanceMainLogger.info('setup start'); - setup(); - performanceMainLogger.info('setup done'); - } - - mountApp(); -} - -function mountApp() { - performanceMainLogger.info('import app'); - const root = document.getElementById('app'); - assertExists(root); - performanceMainLogger.info('render app'); - createRoot(root).render( - - - - ); -} - -try { - main(); -} catch (err) { - console.error('Failed to bootstrap app', err); -} +export * from './web'; diff --git a/packages/frontend/core/src/web.ts b/packages/frontend/core/src/web.ts index b1b41ac41..3c6b5aa91 100644 --- a/packages/frontend/core/src/web.ts +++ b/packages/frontend/core/src/web.ts @@ -1,6 +1,8 @@ import { configureWorkspaceImplServices } from '@affine/workspace-impl'; -import type { ServiceCollection } from '@toeverything/infra'; -import { configureInfraServices } from '@toeverything/infra'; +import { + configureInfraServices, + type ServiceCollection, +} from '@toeverything/infra'; import { configureBusinessServices, diff --git a/packages/frontend/electron/package.json b/packages/frontend/electron/package.json index f30e954c2..90790ee42 100644 --- a/packages/frontend/electron/package.json +++ b/packages/frontend/electron/package.json @@ -23,7 +23,10 @@ "main": "./dist/main.js", "devDependencies": { "@affine-test/kit": "workspace:*", + "@affine/component": "workspace:*", + "@affine/core": "workspace:*", "@affine/env": "workspace:*", + "@affine/i18n": "workspace:*", "@affine/native": "workspace:*", "@blocksuite/blocks": "0.13.0-canary-202403140735-2367cd5", "@blocksuite/lit": "0.13.0-canary-202403140735-2367cd5", @@ -38,6 +41,7 @@ "@electron-forge/maker-zip": "^7.3.0", "@electron-forge/plugin-auto-unpack-natives": "^7.3.0", "@electron-forge/shared-types": "^7.3.0", + "@emotion/react": "^11.11.4", "@pengx17/electron-forge-maker-appimage": "^1.0.2", "@toeverything/infra": "workspace:*", "@types/uuid": "^9.0.8", @@ -51,7 +55,11 @@ "fs-extra": "^11.2.0", "glob": "^10.3.10", "jotai": "^2.6.5", + "jotai-devtools": "^0.8.0", "lodash-es": "^4.17.21", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.22.3", "rxjs": "^7.8.1", "semver": "^7.6.0", "tinykeys": "patch:tinykeys@npm%3A2.1.0#~/.yarn/patches/tinykeys-npm-2.1.0-819feeaed0.patch", diff --git a/packages/frontend/core/src/app.tsx b/packages/frontend/electron/renderer/app.tsx similarity index 65% rename from packages/frontend/core/src/app.tsx rename to packages/frontend/electron/renderer/app.tsx index 07b360424..a75c38f4e 100644 --- a/packages/frontend/core/src/app.tsx +++ b/packages/frontend/electron/renderer/app.tsx @@ -4,24 +4,24 @@ import '@affine/component/theme/theme.css'; import { AffineContext } from '@affine/component/context'; import { GlobalLoading } from '@affine/component/global-loading'; import { NotificationCenter } from '@affine/component/notification-center'; +import { WorkspaceFallback } from '@affine/core/components/workspace'; +import { GlobalScopeProvider } from '@affine/core/modules/infra-web/global-scope'; +import { CloudSessionProvider } from '@affine/core/providers/session-provider'; +import { router } from '@affine/core/router'; +import { + performanceLogger, + performanceRenderLogger, +} from '@affine/core/shared'; +import createEmotionCache from '@affine/core/utils/create-emotion-cache'; +import { configureWebServices } from '@affine/core/web'; import { createI18n, setUpLanguage } from '@affine/i18n'; import { CacheProvider } from '@emotion/react'; import { getCurrentStore } from '@toeverything/infra/atom'; -import { - ServiceCollection, - ServiceProviderContext, -} from '@toeverything/infra/di'; +import { ServiceCollection } from '@toeverything/infra/di'; import type { PropsWithChildren, ReactElement } from 'react'; -import { lazy, memo, Suspense } from 'react'; +import { lazy, Suspense } from 'react'; import { RouterProvider } from 'react-router-dom'; -import { WorkspaceFallback } from './components/workspace'; -import { CloudSessionProvider } from './providers/session-provider'; -import { router } from './router'; -import { performanceLogger, performanceRenderLogger } from './shared'; -import createEmotionCache from './utils/create-emotion-cache'; -import { configureWebServices } from './web'; - const performanceI18nLogger = performanceLogger.namespace('i18n'); const cache = createEmotionCache(); @@ -43,16 +43,14 @@ const future = { } as const; async function loadLanguage() { - if (environment.isBrowser) { - performanceI18nLogger.info('start'); + performanceI18nLogger.info('start'); - const i18n = createI18n(); - document.documentElement.lang = i18n.language; + const i18n = createI18n(); + document.documentElement.lang = i18n.language; - performanceI18nLogger.info('set up'); - await setUpLanguage(i18n); - performanceI18nLogger.info('done'); - } + performanceI18nLogger.info('set up'); + await setUpLanguage(i18n); + performanceI18nLogger.info('done'); } let languageLoadingPromise: Promise | null = null; @@ -61,7 +59,7 @@ const services = new ServiceCollection(); configureWebServices(services); const serviceProvider = services.provider(); -export const App = memo(function App() { +export function App() { performanceRenderLogger.info('App'); if (!languageLoadingPromise) { @@ -70,15 +68,13 @@ export const App = memo(function App() { return ( - + - {runtimeConfig.enableNotificationCenter && ( - - )} + } router={router} @@ -88,7 +84,7 @@ export const App = memo(function App() { - + ); -}); +} diff --git a/packages/frontend/electron/renderer/index.tsx b/packages/frontend/electron/renderer/index.tsx new file mode 100644 index 000000000..5a425e009 --- /dev/null +++ b/packages/frontend/electron/renderer/index.tsx @@ -0,0 +1,43 @@ +// Side effect import, "declare global" +import '@affine/env/constant'; + +import { setup } from '@affine/core/bootstrap/setup'; +import { performanceLogger } from '@affine/core/shared'; +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; + +import { App } from './app'; + +const performanceMainLogger = performanceLogger.namespace('main'); +function main() { + performanceMainLogger.info('start'); + + // skip bootstrap setup for desktop onboarding + if (window.appInfo?.windowName === 'onboarding') { + performanceMainLogger.info('skip setup'); + } else { + performanceMainLogger.info('setup start'); + setup(); + performanceMainLogger.info('setup done'); + } + + mountApp(); +} + +function mountApp() { + performanceMainLogger.info('import app'); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const root = document.getElementById('app')!; + performanceMainLogger.info('render app'); + createRoot(root).render( + + + + ); +} + +try { + main(); +} catch (err) { + console.error('Failed to bootstrap app', err); +} diff --git a/packages/frontend/electron/renderer/tsconfig.json b/packages/frontend/electron/renderer/tsconfig.json new file mode 100644 index 000000000..a6fc1fd95 --- /dev/null +++ b/packages/frontend/electron/renderer/tsconfig.json @@ -0,0 +1,29 @@ +{ + "extends": "../../../../tsconfig.json", + "compilerOptions": { + "composite": true, + "target": "ESNext", + "module": "ESNext", + "resolveJsonModule": true, + "moduleResolution": "Bundler", + "allowSyntheticDefaultImports": true, + "noEmit": false, + "outDir": "../lib", + "allowJs": true + }, + "references": [ + { + "path": "../../../common/env" + }, + { + "path": "../../core" + }, + { + "path": "../../component" + }, + { + "path": "../../../common/infra" + } + ], + "include": ["."] +} diff --git a/packages/frontend/electron/scripts/generate-assets.ts b/packages/frontend/electron/scripts/generate-assets.ts index 6f1347eb2..429c2d4e2 100755 --- a/packages/frontend/electron/scripts/generate-assets.ts +++ b/packages/frontend/electron/scripts/generate-assets.ts @@ -12,8 +12,8 @@ const __dirname = fileURLToPath(new URL('.', import.meta.url)); const repoRootDir = path.join(__dirname, '..', '..', '..', '..'); const electronRootDir = path.join(__dirname, '..'); const publicDistDir = path.join(electronRootDir, 'resources'); -const affineCoreDir = path.join(repoRootDir, 'packages', 'frontend', 'core'); -const affineCoreOutDir = path.join(affineCoreDir, 'dist'); +const webDir = path.join(repoRootDir, 'packages', 'frontend', 'electron'); +const affineWebOutDir = path.join(webDir, 'dist'); const publicAffineOutDir = path.join(publicDistDir, `web-static`); const releaseVersionEnv = process.env.RELEASE_VERSION || ''; @@ -21,8 +21,8 @@ console.log('build with following variables', { repoRootDir, electronRootDir, publicDistDir, - affineSrcDir: affineCoreDir, - affineSrcOutDir: affineCoreOutDir, + affineSrcDir: webDir, + affineSrcOutDir: affineWebOutDir, publicAffineOutDir, releaseVersionEnv, }); @@ -45,7 +45,7 @@ const nxFlag = SKIP_NX_CACHE ? '--skip-nx-cache' : ''; // step 1: build web dist if (!process.env.SKIP_WEB_BUILD) { - spawnSync('yarn', ['nx', 'build', '@affine/core', nxFlag], { + spawnSync('yarn', ['nx', 'build', '@affine/web', nxFlag], { stdio: 'inherit', env: process.env, cwd, @@ -58,10 +58,10 @@ if (!process.env.SKIP_WEB_BUILD) { }); // step 1.5: amend sourceMappingURL to allow debugging in devtools - await glob('**/*.{js,css}', { cwd: affineCoreOutDir }).then(files => { + await glob('**/*.{js,css}', { cwd: affineWebOutDir }).then(files => { return files.map(async file => { const dir = path.dirname(file); - const fullpath = path.join(affineCoreOutDir, file); + const fullpath = path.join(affineWebOutDir, file); let content = await fs.readFile(fullpath, 'utf-8'); // replace # sourceMappingURL=76-6370cd185962bc89.js.map // to # sourceMappingURL=assets://./{dir}/76-6370cd185962bc89.js.map @@ -78,7 +78,7 @@ if (!process.env.SKIP_WEB_BUILD) { }); }); - await fs.move(affineCoreOutDir, publicAffineOutDir, { overwrite: true }); + await fs.move(affineWebOutDir, publicAffineOutDir, { overwrite: true }); } // step 2: update app-updater.yml content with build type in resources folder diff --git a/packages/frontend/electron/tsconfig.json b/packages/frontend/electron/tsconfig.json index f207aca9f..d9318764d 100644 --- a/packages/frontend/electron/tsconfig.json +++ b/packages/frontend/electron/tsconfig.json @@ -14,7 +14,7 @@ "noImplicitOverride": true }, "include": ["./src"], - "exclude": ["node_modules", "lib", "dist", "**/__tests__/**/*"], + "exclude": ["renderer", "node_modules", "lib", "dist", "**/__tests__/**/*"], "references": [ { "path": "../../frontend/native" diff --git a/packages/frontend/templates/build-edgeless.mjs b/packages/frontend/templates/build-edgeless.mjs index 46294979d..43762c2b1 100644 --- a/packages/frontend/templates/build-edgeless.mjs +++ b/packages/frontend/templates/build-edgeless.mjs @@ -306,9 +306,5 @@ export const builtInTemplates = { }); }; -async function main() { - const templatesInGroup = await parseSnapshot(); - await buildScript(templatesInGroup); -} - -main(); +const templatesInGroup = await parseSnapshot(); +await buildScript(templatesInGroup); diff --git a/packages/frontend/templates/package.json b/packages/frontend/templates/package.json index 016f5b850..51f1397b6 100644 --- a/packages/frontend/templates/package.json +++ b/packages/frontend/templates/package.json @@ -9,7 +9,8 @@ "type": "module", "exports": { ".": "./templates.gen.ts", - "./edgeless": "./edgeless-templates.gen.ts" + "./edgeless": "./edgeless-templates.gen.ts", + "./build-edgeless": "./build-edgeless.mjs" }, "devDependencies": { "jszip": "^3.10.1" diff --git a/packages/frontend/web/package.json b/packages/frontend/web/package.json new file mode 100644 index 000000000..afa91f82e --- /dev/null +++ b/packages/frontend/web/package.json @@ -0,0 +1,27 @@ +{ + "name": "@affine/web", + "version": "0.0.0", + "description": "AFFiNE Desktop Web application", + "private": true, + "browser": "src/index.tsx", + "scripts": { + "build": "yarn workspace @affine/cli build", + "dev": "yarn workspace @affine/cli dev", + "static-server": "yarn workspace @affine/cli dev --static" + }, + "dependencies": { + "@affine/component": "workspace:*", + "@affine/core": "workspace:*", + "@affine/env": "workspace:*", + "@juggle/resize-observer": "^3.4.0", + "intl-segmenter-polyfill-rs": "^0.1.7", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@affine/cli": "workspace:*", + "@types/react": "^18.2.60", + "@types/react-dom": "^18.2.19", + "typescript": "^5.3.3" + } +} diff --git a/packages/frontend/core/project.json b/packages/frontend/web/project.json similarity index 92% rename from packages/frontend/core/project.json rename to packages/frontend/web/project.json index d3b47167a..088d3707b 100644 --- a/packages/frontend/core/project.json +++ b/packages/frontend/web/project.json @@ -1,5 +1,5 @@ { - "name": "@affine/core", + "name": "@affine/web", "$schema": "../../../node_modules/nx/schemas/project-schema.json", "targets": { "build": { @@ -13,9 +13,9 @@ "^build" ], "inputs": [ - "{projectRoot}/.webpack/**/*", "{projectRoot}/**/*", - "{projectRoot}/public/**/*", + "{workspaceRoot}/tools/**/*", + "{workspaceRoot}/packages/frontend/core/**/*", "{workspaceRoot}/packages/**/*", { "env": "BUILD_TYPE" diff --git a/packages/frontend/web/src/app.tsx b/packages/frontend/web/src/app.tsx new file mode 100644 index 000000000..a75c38f4e --- /dev/null +++ b/packages/frontend/web/src/app.tsx @@ -0,0 +1,90 @@ +import '@affine/component/theme/global.css'; +import '@affine/component/theme/theme.css'; + +import { AffineContext } from '@affine/component/context'; +import { GlobalLoading } from '@affine/component/global-loading'; +import { NotificationCenter } from '@affine/component/notification-center'; +import { WorkspaceFallback } from '@affine/core/components/workspace'; +import { GlobalScopeProvider } from '@affine/core/modules/infra-web/global-scope'; +import { CloudSessionProvider } from '@affine/core/providers/session-provider'; +import { router } from '@affine/core/router'; +import { + performanceLogger, + performanceRenderLogger, +} from '@affine/core/shared'; +import createEmotionCache from '@affine/core/utils/create-emotion-cache'; +import { configureWebServices } from '@affine/core/web'; +import { createI18n, setUpLanguage } from '@affine/i18n'; +import { CacheProvider } from '@emotion/react'; +import { getCurrentStore } from '@toeverything/infra/atom'; +import { ServiceCollection } from '@toeverything/infra/di'; +import type { PropsWithChildren, ReactElement } from 'react'; +import { lazy, Suspense } from 'react'; +import { RouterProvider } from 'react-router-dom'; + +const performanceI18nLogger = performanceLogger.namespace('i18n'); +const cache = createEmotionCache(); + +const DevTools = lazy(() => + import('jotai-devtools').then(m => ({ default: m.DevTools })) +); + +const DebugProvider = ({ children }: PropsWithChildren): ReactElement => { + return ( + <> + {process.env.DEBUG_JOTAI === 'true' && } + {children} + + ); +}; + +const future = { + v7_startTransition: true, +} as const; + +async function loadLanguage() { + performanceI18nLogger.info('start'); + + const i18n = createI18n(); + document.documentElement.lang = i18n.language; + + performanceI18nLogger.info('set up'); + await setUpLanguage(i18n); + performanceI18nLogger.info('done'); +} + +let languageLoadingPromise: Promise | null = null; + +const services = new ServiceCollection(); +configureWebServices(services); +const serviceProvider = services.provider(); + +export function App() { + performanceRenderLogger.info('App'); + + if (!languageLoadingPromise) { + languageLoadingPromise = loadLanguage().catch(console.error); + } + + return ( + + + + + + + + + } + router={router} + future={future} + /> + + + + + + + ); +} diff --git a/packages/frontend/web/src/index.tsx b/packages/frontend/web/src/index.tsx new file mode 100644 index 000000000..a2b6ed229 --- /dev/null +++ b/packages/frontend/web/src/index.tsx @@ -0,0 +1,45 @@ +import './polyfill/intl-segmenter'; +import './polyfill/request-idle-callback'; +import './polyfill/resize-observer'; + +import { setup } from '@affine/core/bootstrap/setup'; +import { performanceLogger } from '@affine/core/shared'; +import { isDesktop } from '@affine/env/constant'; +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; + +import { App } from './app'; + +const performanceMainLogger = performanceLogger.namespace('main'); +function main() { + performanceMainLogger.info('start'); + + // skip bootstrap setup for desktop onboarding + if (isDesktop && window.appInfo?.windowName === 'onboarding') { + performanceMainLogger.info('skip setup'); + } else { + performanceMainLogger.info('setup start'); + setup(); + performanceMainLogger.info('setup done'); + } + + mountApp(); +} + +function mountApp() { + performanceMainLogger.info('import app'); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const root = document.getElementById('app')!; + performanceMainLogger.info('render app'); + createRoot(root).render( + + + + ); +} + +try { + main(); +} catch (err) { + console.error('Failed to bootstrap app', err); +} diff --git a/packages/frontend/core/src/polyfill/intl-segmenter.ts b/packages/frontend/web/src/polyfill/intl-segmenter.ts similarity index 100% rename from packages/frontend/core/src/polyfill/intl-segmenter.ts rename to packages/frontend/web/src/polyfill/intl-segmenter.ts diff --git a/packages/frontend/core/src/polyfill/request-idle-callback.ts b/packages/frontend/web/src/polyfill/request-idle-callback.ts similarity index 100% rename from packages/frontend/core/src/polyfill/request-idle-callback.ts rename to packages/frontend/web/src/polyfill/request-idle-callback.ts diff --git a/packages/frontend/core/src/polyfill/resize-observer.ts b/packages/frontend/web/src/polyfill/resize-observer.ts similarity index 100% rename from packages/frontend/core/src/polyfill/resize-observer.ts rename to packages/frontend/web/src/polyfill/resize-observer.ts diff --git a/packages/frontend/web/tsconfig.json b/packages/frontend/web/tsconfig.json new file mode 100644 index 000000000..af59eddff --- /dev/null +++ b/packages/frontend/web/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "composite": true, + "outDir": "lib", + "moduleResolution": "Bundler", + "types": ["affine__env"], + "rootDir": "./src" + }, + "include": ["./src"], + "references": [{ "path": "../core" }] +} diff --git a/scripts/download-blocksuite-fonts.mjs b/scripts/download-blocksuite-fonts.mjs index 313987baa..041364403 100644 --- a/scripts/download-blocksuite-fonts.mjs +++ b/scripts/download-blocksuite-fonts.mjs @@ -11,7 +11,7 @@ const fontPath = join( '..', 'packages', 'frontend', - 'core', + 'web', 'dist', 'assets' ); diff --git a/scripts/setup/global.ts b/scripts/setup/global.ts index f03587e54..7aab93eae 100644 --- a/scripts/setup/global.ts +++ b/scripts/setup/global.ts @@ -1,7 +1,6 @@ +import { getRuntimeConfig } from '@affine/cli/src/webpack/runtime-config'; import { setupGlobal } from '@affine/env/global'; -import { getRuntimeConfig } from '../../packages/frontend/core/.webpack/runtime-config'; - globalThis.runtimeConfig = getRuntimeConfig({ distribution: 'browser', mode: 'development', diff --git a/tests/storybook/.storybook/main.ts b/tests/storybook/.storybook/main.ts index 3ef0ef386..6f4dc03f7 100644 --- a/tests/storybook/.storybook/main.ts +++ b/tests/storybook/.storybook/main.ts @@ -3,7 +3,7 @@ import type { StorybookConfig } from '@storybook/react-vite'; import { fileURLToPath } from 'node:url'; import { mergeConfig } from 'vite'; import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; -import { getRuntimeConfig } from '../../../packages/frontend/core/.webpack/runtime-config'; +import { getRuntimeConfig } from '@affine/cli/src/webpack/runtime-config'; runCli( { diff --git a/tests/storybook/package.json b/tests/storybook/package.json index 96314973a..45ff53e11 100644 --- a/tests/storybook/package.json +++ b/tests/storybook/package.json @@ -7,6 +7,7 @@ "test": "test-storybook" }, "dependencies": { + "@affine/cli": "workspace:*", "@affine/component": "workspace:*", "@affine/i18n": "workspace:*", "@affine/workspace-impl": "workspace:*", diff --git a/tests/storybook/tsconfig.json b/tests/storybook/tsconfig.json index fadad8d01..e6760b1f9 100644 --- a/tests/storybook/tsconfig.json +++ b/tests/storybook/tsconfig.json @@ -15,6 +15,9 @@ { "path": "../../packages/frontend/component" }, + { + "path": "../../tools/cli" + }, { "path": "../../packages/common/env" }, diff --git a/tools/cli/package.json b/tools/cli/package.json index 39c94f805..c140b74c9 100644 --- a/tools/cli/package.json +++ b/tools/cli/package.json @@ -2,25 +2,45 @@ "name": "@affine/cli", "type": "module", "private": true, - "bin": { - "build-core": "./src/bin/build-core.mjs", - "dev-core": "./src/bin/dev-core.mjs" - }, - "exports": { - "./config": "./src/config/index.ts" - }, "devDependencies": { + "@affine/env": "workspace:*", + "@affine/templates": "workspace:*", + "@aws-sdk/client-s3": "3.536.0", + "@blocksuite/presets": "0.13.0-canary-202403140735-2367cd5", "@clack/core": "^0.3.4", "@clack/prompts": "^0.7.0", "@magic-works/i18n-codegen": "^0.5.0", - "ts-node": "^10.9.2" - }, - "dependencies": { + "@napi-rs/simple-git": "^0.1.16", + "@perfsee/webpack": "^1.12.2", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", + "@sentry/webpack-plugin": "^2.14.2", + "@types/webpack-env": "^1.18.4", + "@vanilla-extract/webpack-plugin": "^2.3.7", + "copy-webpack-plugin": "^12.0.2", + "css-loader": "^6.10.0", + "cssnano": "^6.1.0", "dotenv": "^16.4.5", - "vite": "^5.1.4" + "html-webpack-plugin": "^5.6.0", + "lodash-es": "^4.17.21", + "mime-types": "^2.1.35", + "mini-css-extract-plugin": "^2.8.1", + "postcss-loader": "^8.1.0", + "raw-loader": "^4.0.2", + "source-map-loader": "^5.0.0", + "style-loader": "^3.3.4", + "swc-loader": "^0.2.6", + "terser-webpack-plugin": "^5.3.10", + "thread-loader": "^4.0.2", + "ts-node": "^10.9.2", + "vite": "^5.1.4", + "webpack": "^5.90.3", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.0.2", + "webpack-merge": "^5.10.0" }, - "peerDependencies": { - "ts-node": "*" + "scripts": { + "build": "node --loader ts-node/esm/transpile-only.mjs ./src/bin/build.ts", + "dev": "node --loader ts-node/esm/transpile-only.mjs ./src/bin/dev.ts" }, "version": "0.14.0" } diff --git a/tools/cli/src/bin/build-core.mjs b/tools/cli/src/bin/build-core.mjs deleted file mode 100755 index 5fe5e4b91..000000000 --- a/tools/cli/src/bin/build-core.mjs +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node -import { spawnSync } from 'node:child_process'; -import { fileURLToPath } from 'node:url'; - -const child = spawnSync( - process.execPath, - [ - '--loader', - 'ts-node/esm/transpile-only', - fileURLToPath(new URL('./build-core.ts', import.meta.url)), - ...process.argv.slice(2), - ], - { stdio: 'inherit' } -); - -if (child.status) process.exit(child.status); diff --git a/tools/cli/src/bin/build-core.ts b/tools/cli/src/bin/build.ts similarity index 61% rename from tools/cli/src/bin/build-core.ts rename to tools/cli/src/bin/build.ts index 1c5b8b909..88d856b81 100644 --- a/tools/cli/src/bin/build-core.ts +++ b/tools/cli/src/bin/build.ts @@ -1,11 +1,13 @@ -import { spawn } from 'node:child_process'; import path from 'node:path'; +import webpack from 'webpack'; + import type { BuildFlags } from '../config/index.js'; import { projectRoot } from '../config/index.js'; import { buildI18N } from '../util/i18n.js'; +import { createWebpackConfig } from '../webpack/webpack.config.js'; -const cwd = path.resolve(projectRoot, 'packages/frontend/core'); +let cwd: string; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const buildType = process.env.BUILD_TYPE_OVERRIDE || process.env.BUILD_TYPE; @@ -31,15 +33,20 @@ const getChannel = () => { } }; +let entry: string | undefined; + +const { DISTRIBUTION } = process.env; + const getDistribution = () => { - switch (process.env.DISTRIBUTION) { + switch (DISTRIBUTION) { case 'browser': - case 'desktop': - return process.env.DISTRIBUTION; - case undefined: { - console.log('DISTRIBUTION is not set, defaulting to browser'); + case undefined: + cwd = path.join(projectRoot, 'packages/frontend/web'); return 'browser'; - } + case 'desktop': + cwd = path.join(projectRoot, 'packages/frontend/electron'); + entry = path.join(cwd, 'renderer', 'index.tsx'); + return DISTRIBUTION; default: { throw new Error('DISTRIBUTION must be one of browser, desktop'); } @@ -51,24 +58,19 @@ const flags = { mode: 'production', channel: getChannel(), coverage: process.env.COVERAGE === 'true', + entry, } satisfies BuildFlags; buildI18N(); -spawn( - 'node', - [ - '--loader', - 'ts-node/esm/transpile-only', - '../../../node_modules/webpack/bin/webpack.js', - '--mode', - 'production', - '--env', - 'flags=' + Buffer.from(JSON.stringify(flags), 'utf-8').toString('hex'), - ].filter((v): v is string => !!v), - { - cwd, - stdio: 'inherit', - shell: true, - env: process.env, + +// eslint-disable-next-line @typescript-eslint/no-non-null-assertion +webpack(createWebpackConfig(cwd!, flags), (err, stats) => { + if (err) { + console.error(err); + process.exit(1); } -); + if (stats?.hasErrors()) { + console.error(stats.toString('errors-only')); + process.exit(1); + } +}); diff --git a/tools/cli/src/bin/dev-core.mjs b/tools/cli/src/bin/dev-core.mjs deleted file mode 100755 index 3049d411f..000000000 --- a/tools/cli/src/bin/dev-core.mjs +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node -import { spawnSync } from 'node:child_process'; -import { fileURLToPath } from 'node:url'; - -const child = spawnSync( - process.execPath, - [ - '--loader', - 'ts-node/esm/transpile-only', - fileURLToPath(new URL('./dev-core.ts', import.meta.url)), - ...process.argv.slice(2), - ], - { stdio: 'inherit' } -); - -if (child.status) process.exit(child.status); diff --git a/tools/cli/src/bin/dev-core.ts b/tools/cli/src/bin/dev-core.ts deleted file mode 100644 index a9432aca4..000000000 --- a/tools/cli/src/bin/dev-core.ts +++ /dev/null @@ -1,207 +0,0 @@ -import type { ChildProcess } from 'node:child_process'; -import { spawn } from 'node:child_process'; -import { existsSync } from 'node:fs'; -import path from 'node:path'; - -import * as p from '@clack/prompts'; -import { config } from 'dotenv'; - -import { type BuildFlags, projectRoot } from '../config/index.js'; -import { watchI18N } from '../util/i18n.js'; - -const cwd = path.resolve(projectRoot, 'packages/frontend/core'); - -const flags: BuildFlags = { - distribution: 'browser', - mode: 'development', - channel: 'canary', - coverage: process.env.COVERAGE === 'true', - localBlockSuite: undefined, -}; - -if (process.argv.includes('--static')) { - await awaitChildProcess( - spawn( - 'node', - [ - '--loader', - 'ts-node/esm/transpile-only', - '../../../node_modules/webpack/bin/webpack.js', - 'serve', - '--mode', - 'development', - '--no-client-overlay', - '--no-live-reload', - '--env', - 'flags=' + Buffer.from(JSON.stringify(flags), 'utf-8').toString('hex'), - ].filter((v): v is string => !!v), - { - cwd, - stdio: 'inherit', - shell: true, - env: process.env, - } - ) - ); - process.exit(0); -} - -const files = ['.env', '.env.local']; - -for (const file of files) { - if (existsSync(path.resolve(projectRoot, file))) { - config({ - path: path.resolve(projectRoot, file), - }); - console.log(`${file} loaded`); - break; - } -} - -const buildFlags = await p.group( - { - distribution: () => - p.select({ - message: 'Distribution', - options: [ - { - value: 'browser', - }, - { - value: 'desktop', - }, - ], - initialValue: 'browser', - }), - mode: () => - p.select({ - message: 'Mode', - options: [ - { - value: 'development', - }, - { - value: 'production', - }, - ], - initialValue: 'development', - }), - channel: () => - p.select({ - message: 'Channel', - options: [ - { - value: 'canary', - }, - { - value: 'beta', - }, - { - value: 'stable', - }, - ], - initialValue: 'canary', - }), - coverage: () => - p.confirm({ - message: 'Enable coverage', - initialValue: process.env.COVERAGE === 'true', - }), - debugBlockSuite: () => - p.confirm({ - message: 'Debug blocksuite locally?', - initialValue: false, - }), - }, - { - onCancel: () => { - p.cancel('Operation cancelled.'); - process.exit(0); - }, - } -); - -if (buildFlags.debugBlockSuite) { - const { config } = await import('dotenv'); - const envLocal = config({ - path: path.resolve(cwd, '.env.local'), - }); - - const localBlockSuite = await p.text({ - message: 'local blocksuite PATH', - initialValue: envLocal.error - ? undefined - : envLocal.parsed?.LOCAL_BLOCK_SUITE, - }); - if (typeof localBlockSuite !== 'string') { - throw new Error('local blocksuite PATH is required'); - } - if (!existsSync(localBlockSuite)) { - throw new Error(`local blocksuite not found: ${localBlockSuite}`); - } - flags.localBlockSuite = localBlockSuite; -} - -flags.distribution = buildFlags.distribution as any; -flags.mode = buildFlags.mode as any; -flags.channel = buildFlags.channel as any; -flags.coverage = buildFlags.coverage; - -watchI18N(); - -function awaitChildProcess(child: ChildProcess): Promise { - return new Promise((resolve, reject) => { - const handleExitCode = (code: number | null) => { - if (code) { - reject( - new Error( - `Child process at ${ - (child as any).cwd - } fails: ${child.spawnargs.join(' ')}` - ) - ); - } else { - resolve(0); - } - }; - - child.on('error', () => handleExitCode(child.exitCode)); - child.on('exit', code => handleExitCode(code)); - }); -} - -try { - await awaitChildProcess( - spawn('node', ['build-edgeless.mjs'], { - cwd: path.resolve(projectRoot, 'packages/frontend/templates'), - stdio: 'inherit', - shell: true, - env: process.env, - }) - ); - // Start webpack - await awaitChildProcess( - spawn( - 'node', - [ - '--loader', - 'ts-node/esm/transpile-only', - '../../../node_modules/webpack/bin/webpack.js', - flags.mode === 'development' ? 'serve' : undefined, - '--mode', - flags.mode === 'development' ? 'development' : 'production', - '--env', - 'flags=' + Buffer.from(JSON.stringify(flags), 'utf-8').toString('hex'), - ].filter((v): v is string => !!v), - { - cwd, - stdio: 'inherit', - shell: true, - env: process.env, - } - ) - ); -} catch (error) { - console.error('Error during build:', error); - process.exit(1); -} diff --git a/tools/cli/src/bin/dev.ts b/tools/cli/src/bin/dev.ts new file mode 100644 index 000000000..b743b1911 --- /dev/null +++ b/tools/cli/src/bin/dev.ts @@ -0,0 +1,143 @@ +import { existsSync } from 'node:fs'; +import { join } from 'node:path'; + +import * as p from '@clack/prompts'; +import { config } from 'dotenv'; +import webpack from 'webpack'; +import WebpackDevServer from 'webpack-dev-server'; + +import { type BuildFlags, projectRoot } from '../config/index.js'; +import { watchI18N } from '../util/i18n.js'; +import { createWebpackConfig } from '../webpack/webpack.config.js'; + +const flags: BuildFlags = { + distribution: 'browser', + mode: 'development', + channel: 'canary', + coverage: process.env.COVERAGE === 'true', + localBlockSuite: undefined, +}; + +const files = ['.env', '.env.local']; + +for (const file of files) { + if (existsSync(join(projectRoot, file))) { + config({ + path: join(projectRoot, file), + }); + console.log(`${file} loaded`); + break; + } +} + +const buildFlags = process.argv.includes('--static') + ? { ...flags, debugBlockSuite: false } + : ((await p.group( + { + distribution: () => + p.select({ + message: 'Distribution', + options: [ + { + value: 'browser', + }, + { + value: 'desktop', + }, + ], + initialValue: 'browser', + }), + mode: () => + p.select({ + message: 'Mode', + options: [ + { + value: 'development', + }, + { + value: 'production', + }, + ], + initialValue: 'development', + }), + channel: () => + p.select({ + message: 'Channel', + options: [ + { + value: 'canary', + }, + { + value: 'beta', + }, + { + value: 'stable', + }, + ], + initialValue: 'canary', + }), + coverage: () => + p.confirm({ + message: 'Enable coverage', + initialValue: process.env.COVERAGE === 'true', + }), + debugBlockSuite: () => + p.confirm({ + message: 'Debug blocksuite locally?', + initialValue: false, + }), + }, + { + onCancel: () => { + p.cancel('Operation cancelled.'); + process.exit(0); + }, + } + )) as BuildFlags & { debugBlockSuite: boolean }); + +flags.distribution = buildFlags.distribution; +flags.mode = buildFlags.mode; +flags.channel = buildFlags.channel; +flags.coverage = buildFlags.coverage; + +const cwd = + flags.distribution === 'browser' + ? join(projectRoot, 'packages', 'frontend', 'web') + : join(projectRoot, 'packages', 'frontend', 'electron'); + +if (buildFlags.debugBlockSuite) { + const { config } = await import('dotenv'); + const envLocal = config({ + path: join(cwd, '.env.local'), + }); + + const localBlockSuite = await p.text({ + message: 'local blocksuite PATH', + initialValue: envLocal.error + ? undefined + : envLocal.parsed?.LOCAL_BLOCK_SUITE, + }); + if (typeof localBlockSuite !== 'string') { + throw new Error('local blocksuite PATH is required'); + } + if (!existsSync(localBlockSuite)) { + throw new Error(`local blocksuite not found: ${localBlockSuite}`); + } + flags.localBlockSuite = localBlockSuite; +} + +watchI18N(); + +try { + // @ts-expect-error no types + await import('@affine/templates/build-edgeless'); + const config = createWebpackConfig(cwd, flags); + const compiler = webpack(config); + // Start webpack + const devServer = new WebpackDevServer(config.devServer, compiler); + + await devServer.start(); +} catch (error) { + console.error('Error during build:', error); + process.exit(1); +} diff --git a/tools/cli/src/config/index.ts b/tools/cli/src/config/index.ts index dbc7442a5..cfb2f74b0 100644 --- a/tools/cli/src/config/index.ts +++ b/tools/cli/src/config/index.ts @@ -6,6 +6,7 @@ export type BuildFlags = { channel: 'stable' | 'beta' | 'canary' | 'internal'; coverage?: boolean; localBlockSuite?: string; + entry?: string; }; export const projectRoot = fileURLToPath( diff --git a/packages/frontend/core/.webpack/cache-group.ts b/tools/cli/src/webpack/cache-group.ts similarity index 97% rename from packages/frontend/core/.webpack/cache-group.ts rename to tools/cli/src/webpack/cache-group.ts index bdbffd942..7f9f028c8 100644 --- a/packages/frontend/core/.webpack/cache-group.ts +++ b/tools/cli/src/webpack/cache-group.ts @@ -69,7 +69,7 @@ export const productionCacheGroups = { test: (module: any) => module.nameForCondition && /\.css$/.test(module.nameForCondition()) && - !/^javascript/.test(module.type), + !module.type.startsWith('javascript'), chunks: 'all' as const, minSize: 1, minChunks: 1, diff --git a/packages/frontend/core/.webpack/config.ts b/tools/cli/src/webpack/config.ts similarity index 94% rename from packages/frontend/core/.webpack/config.ts rename to tools/cli/src/webpack/config.ts index 42fb5acac..c37953486 100644 --- a/packages/frontend/core/.webpack/config.ts +++ b/tools/cli/src/webpack/config.ts @@ -1,29 +1,27 @@ +import { createRequire } from 'node:module'; import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { createRequire } from 'node:module'; -import type { Configuration as DevServerConfiguration } from 'webpack-dev-server'; +import type { RuntimeConfig } from '@affine/env/global'; import { PerfseePlugin } from '@perfsee/webpack'; -import { sentryWebpackPlugin } from '@sentry/webpack-plugin'; - -import CopyPlugin from 'copy-webpack-plugin'; import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; +import { sentryWebpackPlugin } from '@sentry/webpack-plugin'; +import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin'; +import CopyPlugin from 'copy-webpack-plugin'; +import { compact } from 'lodash-es'; +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import TerserPlugin from 'terser-webpack-plugin'; import webpack from 'webpack'; -import MiniCssExtractPlugin from 'mini-css-extract-plugin'; -import { compact } from 'lodash-es'; +import type { Configuration as DevServerConfiguration } from 'webpack-dev-server'; +import { type BuildFlags, projectRoot } from '../config/index.js'; import { productionCacheGroups } from './cache-group.js'; -import type { BuildFlags } from '@affine/cli/config'; -import { projectRoot } from '@affine/cli/config'; -import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin'; -import type { RuntimeConfig } from '@affine/env/global'; import { WebpackS3Plugin } from './s3-plugin.js'; const IN_CI = !!process.env.CI; export const rootPath = join(fileURLToPath(import.meta.url), '..', '..'); -const workspaceRoot = join(rootPath, '..', '..', '..'); +export const workspaceRoot = join(rootPath, '..', '..', '..'); const require = createRequire(rootPath); @@ -89,15 +87,15 @@ export const getPublicPath = (buildFlags: BuildFlags) => { }; export const createConfiguration: ( + cwd: string, buildFlags: BuildFlags, runtimeConfig: RuntimeConfig -) => webpack.Configuration = (buildFlags, runtimeConfig) => { +) => webpack.Configuration = (cwd, buildFlags, runtimeConfig) => { const blocksuiteBaseDir = buildFlags.localBlockSuite; - const config = { name: 'affine', // to set a correct base path for the source map - context: projectRoot, + context: cwd, experiments: { topLevelAwait: true, outputModule: false, @@ -124,7 +122,7 @@ export const createConfiguration: ( devtoolModuleFilenameTemplate: 'webpack://[namespace]/[resource-path]', hotUpdateChunkFilename: 'hot/[id].[fullhash].js', hotUpdateMainFilename: 'hot/[runtime].[fullhash].json', - path: join(rootPath, 'dist'), + path: join(cwd, 'dist'), clean: buildFlags.mode === 'production', globalObject: 'globalThis', publicPath: getPublicPath(buildFlags), @@ -315,7 +313,7 @@ export const createConfiguration: ( postcssOptions: { config: resolve( rootPath, - '.webpack', + 'webpack', 'postcss.config.cjs' ), }, @@ -356,8 +354,9 @@ export const createConfiguration: ( new CopyPlugin({ patterns: [ { - from: resolve(rootPath, 'public'), - to: resolve(rootPath, 'dist'), + // copy the shared public assets into dist + from: join(workspaceRoot, 'packages', 'frontend', 'core', 'public'), + to: join(cwd, 'dist'), }, ], }), @@ -375,11 +374,24 @@ export const createConfiguration: ( overlay: process.env.DISABLE_DEV_OVERLAY === 'true' ? false : undefined, }, historyApiFallback: true, - static: { - directory: resolve(rootPath, 'public'), - publicPath: '/', - watch: true, - }, + static: [ + { + directory: join( + projectRoot, + 'packages', + 'frontend', + 'core', + 'public' + ), + publicPath: '/', + watch: true, + }, + { + directory: join(cwd, 'public'), + publicPath: '/', + watch: true, + }, + ], proxy: [ { context: '/api/worker/', diff --git a/packages/frontend/core/.webpack/postcss.config.cjs b/tools/cli/src/webpack/postcss.config.cjs similarity index 100% rename from packages/frontend/core/.webpack/postcss.config.cjs rename to tools/cli/src/webpack/postcss.config.cjs diff --git a/packages/frontend/core/.webpack/runtime-config.ts b/tools/cli/src/webpack/runtime-config.ts similarity index 90% rename from packages/frontend/core/.webpack/runtime-config.ts rename to tools/cli/src/webpack/runtime-config.ts index 201837f8b..4121714cc 100644 --- a/packages/frontend/core/.webpack/runtime-config.ts +++ b/tools/cli/src/webpack/runtime-config.ts @@ -1,9 +1,7 @@ import type { RuntimeConfig } from '@affine/env/global'; -import type { BuildFlags } from '@affine/cli/config'; -import { createRequire } from 'node:module'; -const require = createRequire(import.meta.url); -const packageJson = require('../package.json'); +import packageJson from '../../package.json' assert { type: 'json' }; +import type { BuildFlags } from '../config'; export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { const buildPreset: Record = { @@ -21,7 +19,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { enableNewSettingUnstableApi: false, enableSQLiteProvider: true, enableMoveDatabase: false, - enableNotificationCenter: true, enableCloud: true, enableCaptcha: true, enableEnhanceShareMode: false, @@ -30,7 +27,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { allowLocalWorkspace: false, serverUrlPrefix: 'https://app.affine.pro', appVersion: packageJson.version, - editorVersion: packageJson.dependencies['@blocksuite/presets'], + editorVersion: packageJson.devDependencies['@blocksuite/presets'], appBuildType: 'stable', }, get beta() { @@ -63,7 +60,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { enableNewSettingUnstableApi: false, enableSQLiteProvider: true, enableMoveDatabase: false, - enableNotificationCenter: true, enableCloud: true, enableCaptcha: true, enableEnhanceShareMode: false, @@ -72,7 +68,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { allowLocalWorkspace: false, serverUrlPrefix: 'https://affine.fail', appVersion: packageJson.version, - editorVersion: packageJson.dependencies['@blocksuite/presets'], + editorVersion: packageJson.devDependencies['@blocksuite/presets'], appBuildType: 'canary', }, }; @@ -105,9 +101,6 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { enableNewSettingUnstableApi: process.env.ENABLE_NEW_SETTING_UNSTABLE_API ? process.env.ENABLE_NEW_SETTING_UNSTABLE_API === 'true' : currentBuildPreset.enableNewSettingUnstableApi, - enableNotificationCenter: process.env.ENABLE_NOTIFICATION_CENTER - ? process.env.ENABLE_NOTIFICATION_CENTER === 'true' - : currentBuildPreset.enableNotificationCenter, enableCloud: process.env.ENABLE_CLOUD ? process.env.ENABLE_CLOUD === 'true' : currentBuildPreset.enableCloud, diff --git a/packages/frontend/core/.webpack/s3-plugin.ts b/tools/cli/src/webpack/s3-plugin.ts similarity index 89% rename from packages/frontend/core/.webpack/s3-plugin.ts rename to tools/cli/src/webpack/s3-plugin.ts index 83b51a790..4cbbe796d 100644 --- a/packages/frontend/core/.webpack/s3-plugin.ts +++ b/tools/cli/src/webpack/s3-plugin.ts @@ -1,5 +1,5 @@ -import { join } from 'node:path'; import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; import type { PutObjectCommandInput } from '@aws-sdk/client-s3'; import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3'; @@ -7,7 +7,7 @@ import { lookup } from 'mime-types'; import type { Compiler, WebpackPluginInstance } from 'webpack'; export const R2_BUCKET = - process.env.R2_BUCKET! ?? + process.env.R2_BUCKET ?? (process.env.BUILD_TYPE === 'canary' ? 'assets-dev' : 'assets-prod'); export class WebpackS3Plugin implements WebpackPluginInstance { @@ -15,7 +15,9 @@ export class WebpackS3Plugin implements WebpackPluginInstance { region: 'auto', endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`, credentials: { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion accessKeyId: process.env.R2_ACCESS_KEY_ID!, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!, }, }); diff --git a/packages/frontend/core/.webpack/template.html b/tools/cli/src/webpack/template.html similarity index 95% rename from packages/frontend/core/.webpack/template.html rename to tools/cli/src/webpack/template.html index 4c0ee9501..9e3a09980 100644 --- a/packages/frontend/core/.webpack/template.html +++ b/tools/cli/src/webpack/template.html @@ -10,7 +10,7 @@ - + diff --git a/packages/frontend/core/.webpack/webpack.config.ts b/tools/cli/src/webpack/webpack.config.ts similarity index 69% rename from packages/frontend/core/.webpack/webpack.config.ts rename to tools/cli/src/webpack/webpack.config.ts index 17460fa87..3a60773b2 100644 --- a/packages/frontend/core/.webpack/webpack.config.ts +++ b/tools/cli/src/webpack/webpack.config.ts @@ -1,13 +1,14 @@ import { execSync } from 'node:child_process'; import { join, resolve } from 'node:path'; +import type { BuildFlags } from '@affine/cli/config'; +import { Repository } from '@napi-rs/simple-git'; +import HTMLPlugin from 'html-webpack-plugin'; import { once } from 'lodash-es'; import { merge } from 'webpack-merge'; -import type { BuildFlags } from '@affine/cli/config'; -import HTMLPlugin from 'html-webpack-plugin'; +import { createConfiguration, rootPath, workspaceRoot } from './config.js'; import { getRuntimeConfig } from './runtime-config.js'; -import { createConfiguration, rootPath } from './config.js'; const DESCRIPTION = `There can be more than Notion and Miro. AFFiNE is a next-gen knowledge base that brings planning, sorting and creating all together.`; @@ -16,27 +17,29 @@ const gitShortHash = once(() => { if (GITHUB_SHA) { return GITHUB_SHA.substring(0, 9); } + const repo = new Repository(workspaceRoot); + const shortSha = repo.head().target()?.substring(0, 9); + if (shortSha) { + return shortSha; + } const sha = execSync(`git rev-parse --short HEAD`, { encoding: 'utf-8', }).trim(); return sha; }); -export default async function (cli_env: any, _: any) { - const flags: BuildFlags = JSON.parse( - Buffer.from(cli_env.flags, 'hex').toString('utf-8') - ); +export function createWebpackConfig(cwd: string, flags: BuildFlags) { console.log('build flags', flags); const runtimeConfig = getRuntimeConfig(flags); console.log('runtime config', runtimeConfig); - const config = createConfiguration(flags, runtimeConfig); + const config = createConfiguration(cwd, flags, runtimeConfig); return merge(config, { entry: { - app: resolve(rootPath, 'src/index.tsx'), + app: flags.entry ?? resolve(cwd, 'src/index.tsx'), }, plugins: [ new HTMLPlugin({ - template: join(rootPath, '.webpack', 'template.html'), + template: join(rootPath, 'webpack', 'template.html'), inject: 'body', scriptLoading: 'module', minify: false, diff --git a/tools/cli/tsconfig.json b/tools/cli/tsconfig.json index 4b140c480..19e739822 100644 --- a/tools/cli/tsconfig.json +++ b/tools/cli/tsconfig.json @@ -6,5 +6,6 @@ "moduleResolution": "Node", "outDir": "lib" }, - "include": ["src"] + "include": ["src", "package.json"], + "references": [{ "path": "../../packages/common/env" }] } diff --git a/tsconfig.json b/tsconfig.json index 90b93e7ca..99656f5fc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -48,6 +48,7 @@ "skipLibCheck": true, // skip all type checks for .d.ts files "paths": { "@affine/core/*": ["./packages/frontend/core/src/*"], + "@affine/core": ["./packages/frontend/core/src/index.ts"], "@affine/cli/*": ["./tools/cli/src/*"], "@affine/server/*": ["./packages/backend/server/src/*"], "@affine/component": ["./packages/frontend/component/src/index"], @@ -90,9 +91,15 @@ { "path": "./packages/frontend/core" }, + { + "path": "./packages/frontend/web" + }, { "path": "./packages/frontend/electron/tsconfig.test.json" }, + { + "path": "./packages/frontend/electron/renderer/tsconfig.json" + }, { "path": "./packages/frontend/graphql" }, diff --git a/tsconfig.node.json b/tsconfig.node.json index 7f8035e2e..c1b97280a 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -7,12 +7,7 @@ "allowSyntheticDefaultImports": true, "outDir": "lib" }, - "include": [ - "vite.config.ts", - "vitest.config.ts", - "scripts", - "packages/frontend/core/.webpack/runtime-config.ts" - ], + "include": ["vite.config.ts", "vitest.config.ts", "scripts"], "references": [ { "path": "./packages/common/env" diff --git a/yarn.lock b/yarn.lock index 84ed689d6..294461a8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -170,17 +170,40 @@ __metadata: version: 0.0.0-use.local resolution: "@affine/cli@workspace:tools/cli" dependencies: + "@affine/env": "workspace:*" + "@affine/templates": "workspace:*" + "@aws-sdk/client-s3": "npm:3.536.0" + "@blocksuite/presets": "npm:0.13.0-canary-202403140735-2367cd5" "@clack/core": "npm:^0.3.4" "@clack/prompts": "npm:^0.7.0" "@magic-works/i18n-codegen": "npm:^0.5.0" + "@napi-rs/simple-git": "npm:^0.1.16" + "@perfsee/webpack": "npm:^1.12.2" + "@pmmmwh/react-refresh-webpack-plugin": "npm:^0.5.11" + "@sentry/webpack-plugin": "npm:^2.14.2" + "@types/webpack-env": "npm:^1.18.4" + "@vanilla-extract/webpack-plugin": "npm:^2.3.7" + copy-webpack-plugin: "npm:^12.0.2" + css-loader: "npm:^6.10.0" + cssnano: "npm:^6.1.0" dotenv: "npm:^16.4.5" + html-webpack-plugin: "npm:^5.6.0" + lodash-es: "npm:^4.17.21" + mime-types: "npm:^2.1.35" + mini-css-extract-plugin: "npm:^2.8.1" + postcss-loader: "npm:^8.1.0" + raw-loader: "npm:^4.0.2" + source-map-loader: "npm:^5.0.0" + style-loader: "npm:^3.3.4" + swc-loader: "npm:^0.2.6" + terser-webpack-plugin: "npm:^5.3.10" + thread-loader: "npm:^4.0.2" ts-node: "npm:^10.9.2" vite: "npm:^5.1.4" - peerDependencies: - ts-node: "*" - bin: - build-core: ./src/bin/build-core.mjs - dev-core: ./src/bin/dev-core.mjs + webpack: "npm:^5.90.3" + webpack-cli: "npm:^5.1.4" + webpack-dev-server: "npm:^5.0.2" + webpack-merge: "npm:^5.10.0" languageName: unknown linkType: soft @@ -198,6 +221,7 @@ __metadata: version: 0.0.0-use.local resolution: "@affine/component@workspace:packages/frontend/component" dependencies: + "@affine/cli": "workspace:*" "@affine/debug": "workspace:*" "@affine/electron-api": "workspace:*" "@affine/graphql": "workspace:*" @@ -289,7 +313,7 @@ __metadata: languageName: unknown linkType: soft -"@affine/core@workspace:packages/frontend/core": +"@affine/core@workspace:*, @affine/core@workspace:packages/frontend/core": version: 0.0.0-use.local resolution: "@affine/core@workspace:packages/frontend/core" dependencies: @@ -318,7 +342,6 @@ __metadata: "@emotion/react": "npm:^11.11.3" "@emotion/server": "npm:^11.11.0" "@emotion/styled": "npm:^11.11.0" - "@juggle/resize-observer": "npm:^3.4.0" "@marsidev/react-turnstile": "npm:^0.5.3" "@perfsee/webpack": "npm:^1.12.2" "@pmmmwh/react-refresh-webpack-plugin": "npm:^0.5.11" @@ -340,7 +363,6 @@ __metadata: "@types/image-blob-reduce": "npm:^4.1.4" "@types/lodash-es": "npm:^4.17.12" "@types/uuid": "npm:^9.0.8" - "@types/webpack-env": "npm:^1.18.4" "@vanilla-extract/css": "npm:^1.14.1" "@vanilla-extract/dynamic": "npm:^2.1.0" animejs: "npm:^3.2.2" @@ -348,10 +370,7 @@ __metadata: bytes: "npm:^3.1.2" clsx: "npm:^2.1.0" cmdk: "patch:cmdk@npm%3A0.2.0#~/.yarn/patches/cmdk-npm-0.2.0-302237a911.patch" - copy-webpack-plugin: "npm:^12.0.2" - css-loader: "npm:^6.10.0" css-spring: "npm:^4.1.0" - cssnano: "npm:^6.0.4" dayjs: "npm:^1.11.10" express: "npm:^4.18.2" fake-indexeddb: "npm:^5.0.2" @@ -359,10 +378,8 @@ __metadata: fractional-indexing: "npm:^3.2.0" graphql: "npm:^16.8.1" history: "npm:^5.3.0" - html-webpack-plugin: "npm:^5.6.0" idb: "npm:^8.0.0" image-blob-reduce: "npm:^4.1.0" - intl-segmenter-polyfill-rs: "npm:^0.1.7" jotai: "npm:^2.6.5" jotai-devtools: "npm:^0.8.0" jotai-effect: "npm:^0.6.0" @@ -372,11 +389,8 @@ __metadata: lottie-react: "npm:^2.4.0" lottie-web: "npm:^5.12.2" mime-types: "npm:^2.1.35" - mini-css-extract-plugin: "npm:^2.8.0" nanoid: "npm:^5.0.6" next-themes: "npm:^0.3.0" - postcss-loader: "npm:^8.1.0" - raw-loader: "npm:^4.0.2" react: "npm:18.2.0" react-dom: "npm:18.2.0" react-error-boundary: "npm:^4.0.12" @@ -386,18 +400,10 @@ __metadata: react-virtuoso: "npm:^4.7.0" rxjs: "npm:^7.8.1" ses: "npm:^1.3.0" - source-map-loader: "npm:^5.0.0" - style-loader: "npm:^3.3.4" - swc-loader: "npm:^0.2.6" swr: "npm:2.2.5" - thread-loader: "npm:^4.0.2" uuid: "npm:^9.0.1" valtio: "npm:^1.13.1" vitest: "npm:1.4.0" - webpack: "npm:^5.90.3" - webpack-cli: "npm:^5.1.4" - webpack-dev-server: "npm:^5.0.2" - webpack-merge: "npm:^5.10.0" y-protocols: "npm:^1.0.6" yjs: "npm:^13.6.12" zod: "npm:^3.22.4" @@ -438,7 +444,10 @@ __metadata: resolution: "@affine/electron@workspace:packages/frontend/electron" dependencies: "@affine-test/kit": "workspace:*" + "@affine/component": "workspace:*" + "@affine/core": "workspace:*" "@affine/env": "workspace:*" + "@affine/i18n": "workspace:*" "@affine/native": "workspace:*" "@blocksuite/blocks": "npm:0.13.0-canary-202403140735-2367cd5" "@blocksuite/lit": "npm:0.13.0-canary-202403140735-2367cd5" @@ -453,6 +462,7 @@ __metadata: "@electron-forge/maker-zip": "npm:^7.3.0" "@electron-forge/plugin-auto-unpack-natives": "npm:^7.3.0" "@electron-forge/shared-types": "npm:^7.3.0" + "@emotion/react": "npm:^11.11.4" "@pengx17/electron-forge-maker-appimage": "npm:^1.0.2" "@toeverything/infra": "workspace:*" "@types/uuid": "npm:^9.0.8" @@ -468,9 +478,13 @@ __metadata: fs-extra: "npm:^11.2.0" glob: "npm:^10.3.10" jotai: "npm:^2.6.5" + jotai-devtools: "npm:^0.8.0" link-preview-js: "npm:^3.0.5" lodash-es: "npm:^4.17.21" nanoid: "npm:^5.0.6" + react: "npm:^18.2.0" + react-dom: "npm:^18.2.0" + react-router-dom: "npm:^6.22.3" rxjs: "npm:^7.8.1" semver: "npm:^7.6.0" tinykeys: "patch:tinykeys@npm%3A2.1.0#~/.yarn/patches/tinykeys-npm-2.1.0-819feeaed0.patch" @@ -624,7 +638,7 @@ __metadata: "@affine/storage": "workspace:*" "@apollo/server": "npm:^4.10.0" "@auth/prisma-adapter": "npm:^1.4.0" - "@aws-sdk/client-s3": "npm:^3.515.0" + "@aws-sdk/client-s3": "npm:^3.536.0" "@google-cloud/opentelemetry-cloud-monitoring-exporter": "npm:^0.17.0" "@google-cloud/opentelemetry-cloud-trace-exporter": "npm:^2.1.0" "@google-cloud/opentelemetry-resource-util": "npm:^2.1.0" @@ -735,6 +749,7 @@ __metadata: version: 0.0.0-use.local resolution: "@affine/storybook@workspace:tests/storybook" dependencies: + "@affine/cli": "workspace:*" "@affine/component": "workspace:*" "@affine/i18n": "workspace:*" "@affine/workspace-impl": "workspace:*" @@ -794,6 +809,24 @@ __metadata: languageName: unknown linkType: soft +"@affine/web@workspace:packages/frontend/web": + version: 0.0.0-use.local + resolution: "@affine/web@workspace:packages/frontend/web" + dependencies: + "@affine/cli": "workspace:*" + "@affine/component": "workspace:*" + "@affine/core": "workspace:*" + "@affine/env": "workspace:*" + "@juggle/resize-observer": "npm:^3.4.0" + "@types/react": "npm:^18.2.60" + "@types/react-dom": "npm:^18.2.19" + intl-segmenter-polyfill-rs: "npm:^0.1.7" + react: "npm:^18.2.0" + react-dom: "npm:^18.2.0" + typescript: "npm:^5.3.3" + languageName: unknown + linkType: soft + "@affine/workers@workspace:tools/workers": version: 0.0.0-use.local resolution: "@affine/workers@workspace:tools/workers" @@ -1239,7 +1272,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-s3@npm:3.536.0, @aws-sdk/client-s3@npm:^3.515.0": +"@aws-sdk/client-s3@npm:3.536.0, @aws-sdk/client-s3@npm:^3.536.0": version: 3.536.0 resolution: "@aws-sdk/client-s3@npm:3.536.0" dependencies: @@ -4441,9 +4474,9 @@ __metadata: languageName: node linkType: hard -"@emotion/react@npm:^11.11.3": - version: 11.11.3 - resolution: "@emotion/react@npm:11.11.3" +"@emotion/react@npm:^11.11.3, @emotion/react@npm:^11.11.4": + version: 11.11.4 + resolution: "@emotion/react@npm:11.11.4" dependencies: "@babel/runtime": "npm:^7.18.3" "@emotion/babel-plugin": "npm:^11.11.0" @@ -4458,7 +4491,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/f7b98557b7d5236296dda48c2fc8a6cde4af7399758496e9f710f85a80c7d66fee1830966caabd7b237601bfdaca4e1add8c681d1ae4cc3d497fe88958d541c4 + checksum: 10/e7da3a1ddc1d72a4179010bdfd17423c13b1a77bf83a8b18271e919fd382d08c62dc2313ed5347acfd1ef85bb1bae8932597647a986e8a1ea1462552716cd495 languageName: node linkType: hard @@ -10931,10 +10964,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.15.1": - version: 1.15.1 - resolution: "@remix-run/router@npm:1.15.1" - checksum: 10/d262285d155f80779894ee1d9ef07e35421986ba2546378dfe0e3b09397ce71becb6a4677e9efcd4155e2bd3f9f7f7ecbc110cd99bacee6dd7d3e5ce51b7caa8 +"@remix-run/router@npm:1.15.3": + version: 1.15.3 + resolution: "@remix-run/router@npm:1.15.3" + checksum: 10/43d402b4ad3dff6dee5c1bc0822aeeb4d885d11c74c45fca7f2f4d7e57853fddbbb813c372919bb3fcc63f95fbcffdd1d4ac1c406857ea07b9d09a09d0562c8e languageName: node linkType: hard @@ -14339,14 +14372,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:>=16, @types/react@npm:^18.2.58": - version: 18.2.58 - resolution: "@types/react@npm:18.2.58" +"@types/react@npm:*, @types/react@npm:>=16, @types/react@npm:^18.2.58, @types/react@npm:^18.2.60": + version: 18.2.60 + resolution: "@types/react@npm:18.2.60" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/ec5e1a7d8acc55551efec7a3d63441d24c7e94b66bf8039944541a8408048668e51b7b4b0b6e8303cdea271b7c6da242cdc7bb8ca501eedf822956edbdbfc67e + checksum: 10/5f2f6091623f13375a5bbc7e5c222cd212b5d6366ead737b76c853f6f52b314db24af5ae3f688d2d49814c668c216858a75433f145311839d8989d46bb3cbecf languageName: node linkType: hard @@ -14812,9 +14845,9 @@ __metadata: languageName: node linkType: hard -"@vanilla-extract/webpack-plugin@npm:^2.3.6": - version: 2.3.6 - resolution: "@vanilla-extract/webpack-plugin@npm:2.3.6" +"@vanilla-extract/webpack-plugin@npm:^2.3.6, @vanilla-extract/webpack-plugin@npm:^2.3.7": + version: 2.3.7 + resolution: "@vanilla-extract/webpack-plugin@npm:2.3.7" dependencies: "@vanilla-extract/integration": "npm:^7.0.0" chalk: "npm:^4.1.1" @@ -14822,7 +14855,7 @@ __metadata: loader-utils: "npm:^2.0.0" peerDependencies: webpack: ^4.30.0 || ^5.20.2 - checksum: 10/9f3c287e4d855ca6767b9527a49c01a9143671b8c80bcd475095bfe8d038c44337aaa7829295a11366ce7ed457656193a486b0ae887235772e56fba12210715f + checksum: 10/ec0ba33d2e4d2b2faff0ccb5ac4df4bbceab9a8f185498bfe2a5741ee8e73564a839e2c2f6547b34d18216e8714cde54e31a828dbcc74509d413745c828efdc4 languageName: node linkType: hard @@ -16762,7 +16795,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.22.2": +"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.22.2, browserslist@npm:^4.23.0": version: 4.23.0 resolution: "browserslist@npm:4.23.0" dependencies: @@ -17790,7 +17823,7 @@ __metadata: languageName: node linkType: hard -"colord@npm:^2.9.1": +"colord@npm:^2.9.3": version: 2.9.3 resolution: "colord@npm:2.9.3" checksum: 10/907a4506d7307e2f580b471b581e992181ed75ab0c6925ece9ca46d88161d2fc50ed15891cd0556d0d9321237ca75afc9d462e4c050b939ef88428517f047f30 @@ -18609,63 +18642,64 @@ __metadata: languageName: node linkType: hard -"cssnano-preset-default@npm:^6.0.4": - version: 6.0.4 - resolution: "cssnano-preset-default@npm:6.0.4" +"cssnano-preset-default@npm:^6.1.0": + version: 6.1.0 + resolution: "cssnano-preset-default@npm:6.1.0" dependencies: + browserslist: "npm:^4.23.0" css-declaration-sorter: "npm:^7.1.1" - cssnano-utils: "npm:^4.0.1" + cssnano-utils: "npm:^4.0.2" postcss-calc: "npm:^9.0.1" - postcss-colormin: "npm:^6.0.2" - postcss-convert-values: "npm:^6.0.3" - postcss-discard-comments: "npm:^6.0.1" - postcss-discard-duplicates: "npm:^6.0.2" - postcss-discard-empty: "npm:^6.0.2" - postcss-discard-overridden: "npm:^6.0.1" - postcss-merge-longhand: "npm:^6.0.2" - postcss-merge-rules: "npm:^6.0.3" - postcss-minify-font-values: "npm:^6.0.1" - postcss-minify-gradients: "npm:^6.0.1" - postcss-minify-params: "npm:^6.0.2" - postcss-minify-selectors: "npm:^6.0.2" - postcss-normalize-charset: "npm:^6.0.1" - postcss-normalize-display-values: "npm:^6.0.1" - postcss-normalize-positions: "npm:^6.0.1" - postcss-normalize-repeat-style: "npm:^6.0.1" - postcss-normalize-string: "npm:^6.0.1" - postcss-normalize-timing-functions: "npm:^6.0.1" - postcss-normalize-unicode: "npm:^6.0.2" - postcss-normalize-url: "npm:^6.0.1" - postcss-normalize-whitespace: "npm:^6.0.1" - postcss-ordered-values: "npm:^6.0.1" - postcss-reduce-initial: "npm:^6.0.2" - postcss-reduce-transforms: "npm:^6.0.1" - postcss-svgo: "npm:^6.0.2" - postcss-unique-selectors: "npm:^6.0.2" + postcss-colormin: "npm:^6.1.0" + postcss-convert-values: "npm:^6.1.0" + postcss-discard-comments: "npm:^6.0.2" + postcss-discard-duplicates: "npm:^6.0.3" + postcss-discard-empty: "npm:^6.0.3" + postcss-discard-overridden: "npm:^6.0.2" + postcss-merge-longhand: "npm:^6.0.4" + postcss-merge-rules: "npm:^6.1.0" + postcss-minify-font-values: "npm:^6.0.3" + postcss-minify-gradients: "npm:^6.0.3" + postcss-minify-params: "npm:^6.1.0" + postcss-minify-selectors: "npm:^6.0.3" + postcss-normalize-charset: "npm:^6.0.2" + postcss-normalize-display-values: "npm:^6.0.2" + postcss-normalize-positions: "npm:^6.0.2" + postcss-normalize-repeat-style: "npm:^6.0.2" + postcss-normalize-string: "npm:^6.0.2" + postcss-normalize-timing-functions: "npm:^6.0.2" + postcss-normalize-unicode: "npm:^6.1.0" + postcss-normalize-url: "npm:^6.0.2" + postcss-normalize-whitespace: "npm:^6.0.2" + postcss-ordered-values: "npm:^6.0.2" + postcss-reduce-initial: "npm:^6.1.0" + postcss-reduce-transforms: "npm:^6.0.2" + postcss-svgo: "npm:^6.0.3" + postcss-unique-selectors: "npm:^6.0.3" peerDependencies: postcss: ^8.4.31 - checksum: 10/65269604c41fcbc08508c644d660cfb0aaf9805ce5cd18fb706a7f87af558a4b6a3578324ead4838afb8b494a54d6e476cad3569ae6ba573b86ebb0d263dd7cd + checksum: 10/f1b15e64b842ae9e2abd4bb06ace1828d35febea852604f923fd03ff0a310a9bd1bb3f4f195c72644d077fc4d42c598ffedad2dc674d89d36eba4e82b132cc15 languageName: node linkType: hard -"cssnano-utils@npm:^4.0.1": - version: 4.0.1 - resolution: "cssnano-utils@npm:4.0.1" +"cssnano-utils@npm:^4.0.2": + version: 4.0.2 + resolution: "cssnano-utils@npm:4.0.2" peerDependencies: postcss: ^8.4.31 - checksum: 10/6a8f5911e31d9fa8daa6287080a5ff3881c041f691e98cc737d67ddb660bb398f33df6c1649c23d2f6bd0e91ea2cabb6db2f53c0a13e5da12f3cd396f7a7fe61 + checksum: 10/f04c6854e75d847c7a43aff835e003d5bc7387ddfc476f0ad3a2d63663d0cec41047d46604c1717bf6b5a8e24e54bb519e465ff78d62c7e073c7cbe2279bebaf languageName: node linkType: hard -"cssnano@npm:^6.0.4": - version: 6.0.4 - resolution: "cssnano@npm:6.0.4" +"cssnano@npm:^6.1.0": + version: 6.1.0 + resolution: "cssnano@npm:6.1.0" dependencies: - cssnano-preset-default: "npm:^6.0.4" + cssnano-preset-default: "npm:^6.1.0" lilconfig: "npm:^3.1.1" peerDependencies: postcss: ^8.4.31 - checksum: 10/b6a94cfa93115d01c290773a818d7247e63e7021e3d14749510daf7858f4d40a6bf20bdee852a64d4cec6554c3f3b9d5164a3bdf3db5cf15059c2b533c63026a + checksum: 10/5afc00c13e6bd6796b09436004fe2711d73b2c194ee8f895db86235ab4da016d7f07dccda724a12b764f2b54fb4928782c3ae0384e93549b50b6c6572af5bc70 languageName: node linkType: hard @@ -18742,9 +18776,9 @@ __metadata: linkType: hard "date-fns@npm:^3.3.1": - version: 3.4.0 - resolution: "date-fns@npm:3.4.0" - checksum: 10/38932c99ad28a69a18bd9e2331d0c86a46146d3e9efc92cbc612400a075785231c3271822948eb0377db738fa8a583aa4782d8246a939fe6f188727ea9323c29 + version: 3.5.0 + resolution: "date-fns@npm:3.5.0" + checksum: 10/d37eff45f97e6c6745072ff2733c63fffa89e91d4bf407c368641b83c05eaa5222f3f1ba2d7f88862c4fc26fbcf4ad2ffac4526ae6a6414c10fcaea411ab71c3 languageName: node linkType: hard @@ -25303,15 +25337,15 @@ __metadata: linkType: hard "lib0@npm:^0.2.74, lib0@npm:^0.2.85, lib0@npm:^0.2.86, lib0@npm:^0.2.89, lib0@npm:^0.2.91": - version: 0.2.91 - resolution: "lib0@npm:0.2.91" + version: 0.2.92 + resolution: "lib0@npm:0.2.92" dependencies: isomorphic.js: "npm:^0.2.4" bin: 0ecdsa-generate-keypair: bin/0ecdsa-generate-keypair.js 0gentesthtml: bin/gentesthtml.js 0serve: bin/0serve.js - checksum: 10/9706a39d9bc9c309bebf4f380dedeca586aa07c4c54466f3c4ffa394c02b45c8339e80390af06acb94b898b601bb8d7828a830df6a7faa46a61dc37c58b489d8 + checksum: 10/214b194fbc07a1f566c0a751f024d3586bd16d52a5037003593b366961287719e780b383ef10b843abd624c6eec402720383066040ce0ae7431090518bccb881 languageName: node linkType: hard @@ -27310,15 +27344,15 @@ __metadata: languageName: node linkType: hard -"mini-css-extract-plugin@npm:^2.8.0": - version: 2.8.0 - resolution: "mini-css-extract-plugin@npm:2.8.0" +"mini-css-extract-plugin@npm:^2.8.1": + version: 2.8.1 + resolution: "mini-css-extract-plugin@npm:2.8.1" dependencies: schema-utils: "npm:^4.0.0" tapable: "npm:^2.2.1" peerDependencies: webpack: ^5.0.0 - checksum: 10/38166b717682d9e8bd4c1426e1b6463d85c1853fb82c0bd9607c1cbeb070db0feb226acd54364633aeaa832f55230e171599936d85d010626c6414597ba0e1ae + checksum: 10/e00f6d19ad1be94701db8e5f126bdf8a9f4739cd8e8eb68690254aac4699c49c872a1ca761461d7d0c37a933f823df5f87674688fe0d568e00e7c0e9d6e5c798 languageName: node linkType: hard @@ -28496,8 +28530,8 @@ __metadata: linkType: hard "openai@npm:^4.28.4": - version: 4.28.4 - resolution: "openai@npm:4.28.4" + version: 4.29.0 + resolution: "openai@npm:4.29.0" dependencies: "@types/node": "npm:^18.11.18" "@types/node-fetch": "npm:^2.6.4" @@ -28510,7 +28544,7 @@ __metadata: web-streams-polyfill: "npm:^3.2.1" bin: openai: bin/cli - checksum: 10/81bf6f832f43aa81c8fca1bd1f8ffde16f02fcfa13d5cb66b64cd9440c7074054a4a766b0c9b6c9217359f96a376619f91e7071121739afe6eb492992ebfd2ec + checksum: 10/940ccfbdd958951c4ef17918f9336f76650a63a4c5fdf1de0dd9e39d254cee2b0a38ea58760e82ad9ff4fa9d8f5c9837f9e451ba835a6f1e2de1a920f21a4297 languageName: node linkType: hard @@ -29352,65 +29386,65 @@ __metadata: languageName: node linkType: hard -"postcss-colormin@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-colormin@npm:6.0.2" +"postcss-colormin@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-colormin@npm:6.1.0" dependencies: - browserslist: "npm:^4.22.2" + browserslist: "npm:^4.23.0" caniuse-api: "npm:^3.0.0" - colord: "npm:^2.9.1" + colord: "npm:^2.9.3" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10/494af1c59389fa7370695326ca484b90f52c6d881922b770308cb8bc5a2fb6d36f51eb9bda197a020744246ad9e8e4532035fcc4dada487d90cfc893bc442e17 + checksum: 10/55a1525de345d953bc7f32ecaa5ee6275ef0277c27d1f97ff06a1bd1a2fedf7f254e36dc1500621f1df20c25a6d2485a74a0b527d8ff74eb90726c76efe2ac8e languageName: node linkType: hard -"postcss-convert-values@npm:^6.0.3": - version: 6.0.3 - resolution: "postcss-convert-values@npm:6.0.3" +"postcss-convert-values@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-convert-values@npm:6.1.0" dependencies: - browserslist: "npm:^4.22.2" + browserslist: "npm:^4.23.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10/606e02e8a1e739b0c2becb1ad145154b3c819dc2d57bacfa74362fb88c6a7f186e5da6ab3c6b10a1525d8353e5bc5607af98822a23703947d6fd14cee3f75baf + checksum: 10/43e9f66af9bdec3c76695f9dde36885abc01f662c370c490b45d895459caab2c5792f906f3ddad107129133e41485a65634da7f699eef916a636e47f6a37a299 languageName: node linkType: hard -"postcss-discard-comments@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-discard-comments@npm:6.0.1" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/0723b18d80d50bcc65c07c973d4640c3fdd437c226a7178ce6ab5ed74ea50fbf9e08b3f7b8d9495c0d47c6832d49169733fd74a57403e002fc871cd5516ee2ea - languageName: node - linkType: hard - -"postcss-discard-duplicates@npm:^6.0.2": +"postcss-discard-comments@npm:^6.0.2": version: 6.0.2 - resolution: "postcss-discard-duplicates@npm:6.0.2" + resolution: "postcss-discard-comments@npm:6.0.2" peerDependencies: postcss: ^8.4.31 - checksum: 10/918ed7eeb537a955172c73a3dfbcde57fd6515a4c993dfe65a4fe5c4f1d7eda07a3811f73b7d6c6b29d9ba1e6a15e77366866335cb56841777387d482a55e6a8 + checksum: 10/c1731ccc8d1e3d910412a61395988d3033365e6532d9e5432ad7c74add8c9dcb0af0c03d4e901bf0d2b59ea4e7297a0c77a547ff2ed1b1cc065559cc0de43b4e languageName: node linkType: hard -"postcss-discard-empty@npm:^6.0.2": +"postcss-discard-duplicates@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-discard-duplicates@npm:6.0.3" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/308e3fb84c35e4703532de1efa5d6e8444cc5f167d0e40f42d7ea3fa3a37d9d636fd10729847d078e0c303eee16f8548d14b6f88a3fce4e38a2b452648465175 + languageName: node + linkType: hard + +"postcss-discard-empty@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-discard-empty@npm:6.0.3" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/bad305572faa066026a295faab37e718cee096589ab827b19c990c55620b2b2a1ce9f0145212651737a66086db01b2676c1927bbb8408c5f9cb42686d5959f00 + languageName: node + linkType: hard + +"postcss-discard-overridden@npm:^6.0.2": version: 6.0.2 - resolution: "postcss-discard-empty@npm:6.0.2" + resolution: "postcss-discard-overridden@npm:6.0.2" peerDependencies: postcss: ^8.4.31 - checksum: 10/3eed50fb937a68a01a051ea8824b89879b31f31e3061322e74f747240141f2447c760bd029493d942be5ec2d383cf393c2d281556e3de0f93c9ceec2a0cbb760 - languageName: node - linkType: hard - -"postcss-discard-overridden@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-discard-overridden@npm:6.0.1" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/e8c1f893a8ba00c05ac1ce592f3eeafacf5e077dcaf65348887f2b42d971802d884bfd3d4e862c95a51b80e9db7b3bcc095db64219fa441cdbf549f5812235c0 + checksum: 10/a38e0fe7a36f83cb9b73c1ba9ee2a48cf93c69ec0ea5753935824ffb71e958e58ae0393171c0f3d0014a397469d09bbb0d56bb5ab80f0280722967e2e273aebb languageName: node linkType: hard @@ -29434,77 +29468,77 @@ __metadata: languageName: node linkType: hard -"postcss-merge-longhand@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-merge-longhand@npm:6.0.2" +"postcss-merge-longhand@npm:^6.0.4": + version: 6.0.4 + resolution: "postcss-merge-longhand@npm:6.0.4" dependencies: postcss-value-parser: "npm:^4.2.0" - stylehacks: "npm:^6.0.2" + stylehacks: "npm:^6.1.0" peerDependencies: postcss: ^8.4.31 - checksum: 10/6d3fc01fd42da04f4c129969712a815a9b308057f46687ee0d306f308acc5ac1f4d36bb21dd5166a754d23a9f9ed189107ad0a035afdd1135350c1e0504ace6e + checksum: 10/5f9626e3386e8f46f3cb2585fedfd1600cd281462038e90714a220bfef28f53e6b5019ab2412c8deb36f962086a5eae46b423a20106e24b70014764d8c5311f1 languageName: node linkType: hard -"postcss-merge-rules@npm:^6.0.3": - version: 6.0.3 - resolution: "postcss-merge-rules@npm:6.0.3" +"postcss-merge-rules@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-merge-rules@npm:6.1.0" dependencies: - browserslist: "npm:^4.22.2" + browserslist: "npm:^4.23.0" caniuse-api: "npm:^3.0.0" - cssnano-utils: "npm:^4.0.1" + cssnano-utils: "npm:^4.0.2" postcss-selector-parser: "npm:^6.0.15" peerDependencies: postcss: ^8.4.31 - checksum: 10/9d0512417f78766d52c5c55638bb17ebfb7809e4f9154ddfa4775efaf513153a3f7d5d264a1a07b8de17365974f4495f7c0c747613ba4a4ea628b18d9d69ec7e + checksum: 10/6efdcb2112cb8b9898c53b89b4be5c10bd8b5e4fdd87e900406d20a4d2c4de3ce5c63c99a2913bfd1da659fabafbd86d127ac71286cf0ff715bd1521ab8ac7a5 languageName: node linkType: hard -"postcss-minify-font-values@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-minify-font-values@npm:6.0.1" +"postcss-minify-font-values@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-minify-font-values@npm:6.0.3" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10/3a8b0a1ce59994a36ada65ba5cee387c0820e7a6e5b7583e2a6639f76c88339a0aa243884f27f72841ded4d63840b6096853d4310de5c4029e4927bc506ef8f5 + checksum: 10/472edb0146d108a0fc6f02eaa6437fb7440439c0af5b63eeb364dd11684905a66b4fb1acee544040eba8a3ce5ed5625a1c5b231184df6d9d48611a4ca096577c languageName: node linkType: hard -"postcss-minify-gradients@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-minify-gradients@npm:6.0.1" +"postcss-minify-gradients@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-minify-gradients@npm:6.0.3" dependencies: - colord: "npm:^2.9.1" - cssnano-utils: "npm:^4.0.1" + colord: "npm:^2.9.3" + cssnano-utils: "npm:^4.0.2" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10/6245fc4dc4ca25f780245266d9aa2d4125453ef52a751ddac01f06672cfae625f07898dd434e0abe63810e642c14bcf1660130969e03d13888094413909cc670 + checksum: 10/696387df1736b951fbc93c10949e7a1bb85bc12564c506c55e704ae483749f52a9ec919dbca461afa91798373041b840976dbdad031b374a4cf4cf96ad8cd4d0 languageName: node linkType: hard -"postcss-minify-params@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-minify-params@npm:6.0.2" +"postcss-minify-params@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-minify-params@npm:6.1.0" dependencies: - browserslist: "npm:^4.22.2" - cssnano-utils: "npm:^4.0.1" + browserslist: "npm:^4.23.0" + cssnano-utils: "npm:^4.0.2" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10/e2d0e91263e7595d9dd87a7825b598f5948a384a446c18f44001963fae643fcf7f1b575cba8ae52cfadd3f04348209bad9d07b8046b15ccb5070171d2b4ce6f1 + checksum: 10/1e1cc3057d9bcc532c70e40628e96e3aea0081d8072dffe983a270a8cd59c03ac585e57d036b70e43d4ee725f274a05a6a8efac5a715f448284e115c13f82a46 languageName: node linkType: hard -"postcss-minify-selectors@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-minify-selectors@npm:6.0.2" +"postcss-minify-selectors@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-minify-selectors@npm:6.0.3" dependencies: postcss-selector-parser: "npm:^6.0.15" peerDependencies: postcss: ^8.4.31 - checksum: 10/5331e6db4ebc07f781a2f5b9eab03f4ec3650d2e472370fe2124886545eba5d7687372a1359ba86686e414ee90efd4f83a00c1da1b88c788f0c19efbb107cef4 + checksum: 10/1d7c8da7ce4f2f8452e1c6052d23436fd7d0440600f613a513d8233ee8feda6abba1dc34d62557a39991a59e830c3f925a45a8b40f650f496db801a468b01a37 languageName: node linkType: hard @@ -29552,136 +29586,136 @@ __metadata: languageName: node linkType: hard -"postcss-normalize-charset@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-charset@npm:6.0.1" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/7198a7bcc92c9bb971aeb7e6d4a00defc1d5ec99f7c97af217a34942972b9c9e587478d44afb8a8a6d8c7afe63835da233957ad9c9e172f7d3b74e14763f01de - languageName: node - linkType: hard - -"postcss-normalize-display-values@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-display-values@npm:6.0.1" - dependencies: - postcss-value-parser: "npm:^4.2.0" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/4201fde08d28cd54d45f800d130c202f76da448c15179e997c96c4cc88cf959f82c04ceac4f21bd7e0be3db8ea7166b4a3a9e2eb0639aea0fdd84bcf349f8413 - languageName: node - linkType: hard - -"postcss-normalize-positions@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-positions@npm:6.0.1" - dependencies: - postcss-value-parser: "npm:^4.2.0" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/8a08ab0105efdd4ef69545e414daccb40cefa09f73df4813a4c708082a75aabd695519bfeeac2edecb4ee35c9e3771565aeb29e8fdc6df5dec0916e5f2da7e48 - languageName: node - linkType: hard - -"postcss-normalize-repeat-style@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-repeat-style@npm:6.0.1" - dependencies: - postcss-value-parser: "npm:^4.2.0" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/d4985a3379ca79bb7e992c4ee1681c344dc8761b1f6ef7b44c377dad56210c1e400b0321eeed48babe3e57f87dd974570749b5f4483481de903feedbf94ec31c - languageName: node - linkType: hard - -"postcss-normalize-string@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-string@npm:6.0.1" - dependencies: - postcss-value-parser: "npm:^4.2.0" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/bef1337c20fffe8ea651cfc34ade83b71a9415e31551e8d4e1dca0a0de767c99f9bedf100d5d9c30afd82d3ee87d563f864e9d78439ff1718a785e6af175cc83 - languageName: node - linkType: hard - -"postcss-normalize-timing-functions@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-timing-functions@npm:6.0.1" - dependencies: - postcss-value-parser: "npm:^4.2.0" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/60ab18b7e785b64920d6e9db637734332bb161bc2a5d2002449121b353c32e6d85a90cbf6c56667dc93ab5622ce985f8dd3295ff507d38b7231797a2a4a26e75 - languageName: node - linkType: hard - -"postcss-normalize-unicode@npm:^6.0.2": +"postcss-normalize-charset@npm:^6.0.2": version: 6.0.2 - resolution: "postcss-normalize-unicode@npm:6.0.2" - dependencies: - browserslist: "npm:^4.22.2" - postcss-value-parser: "npm:^4.2.0" + resolution: "postcss-normalize-charset@npm:6.0.2" peerDependencies: postcss: ^8.4.31 - checksum: 10/63e41ec27af5c93b6a4172e2406ed930451d5638b2f354bb0e3c7a441b4f40d6ab96e474aabb06c681a0ebc71d11a1fbfeca50493d02d2a1eb094cf5bae7d853 + checksum: 10/5b8aeb17d61578a8656571cd5d5eefa8d4ee7126a99a41fdd322078002a06f2ae96f649197b9c01067a5f3e38a2e4b03e0e3fda5a0ec9e3d7ad056211ce86156 languageName: node linkType: hard -"postcss-normalize-url@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-url@npm:6.0.1" - dependencies: - postcss-value-parser: "npm:^4.2.0" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/a4adcadcbde44b71f2996c23c6671826a7655ab1008413e32cd068a57b60e33950d918e7409ce210e8ee761a33523b5a1879d42927d104b5aee85c27f8bd7dc5 - languageName: node - linkType: hard - -"postcss-normalize-whitespace@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-whitespace@npm:6.0.1" - dependencies: - postcss-value-parser: "npm:^4.2.0" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/cc1c253cb8e66e9b24ce285eace7bca241af0c6f74b027193f41f7c265ef196ad80f9373e4399dd42b63a1d78ffb68d5a22e0530db217bbb5efe7cc031a509bb - languageName: node - linkType: hard - -"postcss-ordered-values@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-ordered-values@npm:6.0.1" - dependencies: - cssnano-utils: "npm:^4.0.1" - postcss-value-parser: "npm:^4.2.0" - peerDependencies: - postcss: ^8.4.31 - checksum: 10/43734feaed392a37f0bc7fb1ba3abf8b6df458781e2e2fc20f38c3709500c80ef5c460bd4581ca2affa7c151287dd0392b57d946bf1917ae91b039308b1ae264 - languageName: node - linkType: hard - -"postcss-reduce-initial@npm:^6.0.2": +"postcss-normalize-display-values@npm:^6.0.2": version: 6.0.2 - resolution: "postcss-reduce-initial@npm:6.0.2" + resolution: "postcss-normalize-display-values@npm:6.0.2" dependencies: - browserslist: "npm:^4.22.2" + postcss-value-parser: "npm:^4.2.0" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/f7bf1e9684d83274861857a0c039b3c293cf46dbfcc69fa68be17f3b69ea87becf872e46cfe4bd3136e45eada73f36ddbb4fe27b074c522455919e9675c078de + languageName: node + linkType: hard + +"postcss-normalize-positions@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-positions@npm:6.0.2" + dependencies: + postcss-value-parser: "npm:^4.2.0" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/44fb77583fae4d71b76e38226cf770570876bcf5af6940dc9aeac7a7e2252896b361e0249044766cff8dad445f925378f06a005d6541597573c20e599a62b516 + languageName: node + linkType: hard + +"postcss-normalize-repeat-style@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-repeat-style@npm:6.0.2" + dependencies: + postcss-value-parser: "npm:^4.2.0" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/7edcea262870315d2c75a5348ea0da24a27f7b34aefaea18cbce8c3419c570b428cfaedd51a32994b0a85a65ef715c219730f8f66d5853769426a3bc09dfff3f + languageName: node + linkType: hard + +"postcss-normalize-string@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-string@npm:6.0.2" + dependencies: + postcss-value-parser: "npm:^4.2.0" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/916b8a3b4115592e4db259467119e71b30feed11437d7d54ee395376e911bd1d13afeb9be4459a0f5d4ac15a4cd8706571b58d67537d3bafbd41dce00cfd77b8 + languageName: node + linkType: hard + +"postcss-normalize-timing-functions@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-timing-functions@npm:6.0.2" + dependencies: + postcss-value-parser: "npm:^4.2.0" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/1970f5aad04be11f99d51c59e27debb6fd7b49d0fa4a8879062b42c82113f8e520a284448727add3b54de85deefb8bd5fe554f618406586e9ad8fc9d060609f1 + languageName: node + linkType: hard + +"postcss-normalize-unicode@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-normalize-unicode@npm:6.1.0" + dependencies: + browserslist: "npm:^4.23.0" + postcss-value-parser: "npm:^4.2.0" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/69ef35d06242061f0c504c128b83752e0f8daa30ebb26734de7d090460910be0b2efd8b17b1d64c3c85b95831a041faad9ad0aaba80e239406a79cfad3d63568 + languageName: node + linkType: hard + +"postcss-normalize-url@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-url@npm:6.0.2" + dependencies: + postcss-value-parser: "npm:^4.2.0" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/bef51a18bbfee4fbf0381fec3c91e6c0dace36fca053bbd5f228e653d2732b6df3985525d79c4f7fc89f840ed07eb6d226e9d7503ecdc6f16d6d80cacae9df33 + languageName: node + linkType: hard + +"postcss-normalize-whitespace@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-whitespace@npm:6.0.2" + dependencies: + postcss-value-parser: "npm:^4.2.0" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/6081eb3a4b305749eec02c00a95c2d236336a77ee636bb1d939f18d5dfa5ba82b7cf7fa072e83f9133d0bc984276596af3fe468bdd67c742ce69e9c63dbc218d + languageName: node + linkType: hard + +"postcss-ordered-values@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-ordered-values@npm:6.0.2" + dependencies: + cssnano-utils: "npm:^4.0.2" + postcss-value-parser: "npm:^4.2.0" + peerDependencies: + postcss: ^8.4.31 + checksum: 10/c3f0f4a27b7c50ea4be18019bd203a7c62b741eaeca86a592ccfabdb1ab14043dbb407f0ede90c64997d62144daa4159cedd1d13a6249e85de5da7f708d92724 + languageName: node + linkType: hard + +"postcss-reduce-initial@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-reduce-initial@npm:6.1.0" + dependencies: + browserslist: "npm:^4.23.0" caniuse-api: "npm:^3.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 10/d6574e317fd03c3c75f26814a3cc9056c12b16e99988aef9797f656b56462b0d6ad20536f23e734d358b6cc0b88b25dc35aa901cc8c822aeccccabe7f426b427 + checksum: 10/41a4c53c76b00a656d3e4c487585f83dd1605cb7c38633042ecbf52b95934b101d6b94d0145f8b5093c3fde699f8e2477206c144af29cd94b1b669d6e387086f languageName: node linkType: hard -"postcss-reduce-transforms@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-reduce-transforms@npm:6.0.1" +"postcss-reduce-transforms@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-reduce-transforms@npm:6.0.2" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10/10bbe19852609eb888cbe35cd8eb7f57d08c122292b31980096d0c16982362ebce4e76b212d056e89c78d4cb6aeac5af2fe6d96f3a940662ea80a4c9535d8a82 + checksum: 10/822730a524159ab7dc91ff5842f6026bcfbcf4ad10d3b3dbca3c26b92a78311b13723550a79bf691f4e6efdf21719e9c263ea25ea13eb3ec0ec830dad4f572c8 languageName: node linkType: hard @@ -29695,26 +29729,26 @@ __metadata: languageName: node linkType: hard -"postcss-svgo@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-svgo@npm:6.0.2" +"postcss-svgo@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-svgo@npm:6.0.3" dependencies: postcss-value-parser: "npm:^4.2.0" svgo: "npm:^3.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10/223255d31e815e6aa2fd1ae0a4ccab6f83590fcbf0cabb39d1a922e577990b4ad9f73989430cb2e2b974b3395d82e9eadcaa13c669fc333aaf2c110483569b97 + checksum: 10/1a7d1c8dea555884a7791e28ec2c22ea92331731067584ff5a23042a0e615f88fefde04e1140f11c262a728ef9fab6851423b40b9c47f9ae05353bd3c0ff051a languageName: node linkType: hard -"postcss-unique-selectors@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-unique-selectors@npm:6.0.2" +"postcss-unique-selectors@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-unique-selectors@npm:6.0.3" dependencies: postcss-selector-parser: "npm:^6.0.15" peerDependencies: postcss: ^8.4.31 - checksum: 10/ab4bb9f0e9117057b63364d79af3f7b6b0b9177c91fc4ff804ec011a0978b7972dd9d10a9bc0ece97ee5fde10c86fd39c51c160ea8425fc0e0414dceb87ef968 + checksum: 10/f504670c186cc2a28cc4b80ff1468476f25a87bd840b83714b7786ae109a47c80feeb6b4597b31559bfe7b0113e3f9e9a494589d65e47e7985c1ba368b7c18c3 languageName: node linkType: hard @@ -30363,7 +30397,7 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:18.2.0": +"react-dom@npm:18.2.0, react-dom@npm:^18.2.0": version: 18.2.0 resolution: "react-dom@npm:18.2.0" dependencies: @@ -30551,27 +30585,27 @@ __metadata: languageName: node linkType: hard -"react-router-dom@npm:^6.22.1": - version: 6.22.1 - resolution: "react-router-dom@npm:6.22.1" +"react-router-dom@npm:^6.22.1, react-router-dom@npm:^6.22.3": + version: 6.22.3 + resolution: "react-router-dom@npm:6.22.3" dependencies: - "@remix-run/router": "npm:1.15.1" - react-router: "npm:6.22.1" + "@remix-run/router": "npm:1.15.3" + react-router: "npm:6.22.3" peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: 10/73ab964083bb407773a5c4ca61249ed6b0a1b47fa58c39afca08a361eb25b349be2bcbaf6d89e112b020f6e55e40e62689c9fe2beae524030ce5ccede3c7d9e3 + checksum: 10/868a530c3167e1903f170818c0162760b8fbe9b10a7a7a79e5998990df341cd7127ba7819af4a9105af72c13453c7c4d76b2b07a70b56fff012fa0508b51940e languageName: node linkType: hard -"react-router@npm:6.22.1": - version: 6.22.1 - resolution: "react-router@npm:6.22.1" +"react-router@npm:6.22.3": + version: 6.22.3 + resolution: "react-router@npm:6.22.3" dependencies: - "@remix-run/router": "npm:1.15.1" + "@remix-run/router": "npm:1.15.3" peerDependencies: react: ">=16.8" - checksum: 10/f6e814b8e3005f16a5fb0e831f0e4352076cde65ab25448d56dba87a43fd3e102f55f9b366bdf1fbd8136fc1dc141bcec8d6b85d45f309e89180fb50f173744d + checksum: 10/df3948afd6500faf4b82a72375b9177536d878d54cad18e20a175efcbfdd0d94852aac59660d786946636ed325284d94a8f46652d898df304d6a29c9a3932afd languageName: node linkType: hard @@ -32875,15 +32909,15 @@ __metadata: languageName: node linkType: hard -"stylehacks@npm:^6.0.2": - version: 6.0.2 - resolution: "stylehacks@npm:6.0.2" +"stylehacks@npm:^6.1.0": + version: 6.1.0 + resolution: "stylehacks@npm:6.1.0" dependencies: - browserslist: "npm:^4.22.2" + browserslist: "npm:^4.23.0" postcss-selector-parser: "npm:^6.0.15" peerDependencies: postcss: ^8.4.31 - checksum: 10/8073a89b9fd6f6070161b20c2e62eb7c2ec7bcfb9fcfb2a30f43b39664b8700171e0d0deb2a7f44ed271f8f72451d0d4ed0068236d0552d27f42f75dddb6d30a + checksum: 10/89bc870a62463a029cb745932b2a2a168136c53b7686acd6869336d590a02ee00bc8578285add2627f63802eccae8884391dec5a6e835c10cb5b3d6ffe430fc8 languageName: node linkType: hard