Compare commits

...

8 Commits

Author SHA1 Message Date
Alex Yang
9d85318082 v0.7.3 2023-08-22 15:26:08 -05:00
Alex Yang
d2316cfdb3 ci: add setup-maker 2023-08-22 15:26:08 -05:00
Peng Xiao
113e4d860c build: sign windows app (#3809) 2023-08-22 15:26:08 -05:00
Alex Yang
27e1a7c171 v0.7.2 2023-08-11 02:10:44 -04:00
Alex Yang
42b90e1d8d fix: remove usage of mergeUpdates (#3687) 2023-08-11 02:09:33 -04:00
Alex Yang
52f01a71d2 v0.7.1 2023-07-30 19:24:31 -07:00
Alex Yang
ab6774bef9 fix(core): migration (#3322) 2023-07-31 10:19:18 +08:00
Alex Yang
7930671a51 v0.7.0 2023-07-27 21:27:37 -07:00
42 changed files with 705 additions and 182 deletions

16
.github/actions/setup-maker/action.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Setup maker
description: 'Setup maker dmg for electron'
runs:
using: 'composite'
steps:
- name: 'Install @electron-forge/maker-dmg'
if: runner.os == 'macos'
shell: bash
working-directory: ./apps/electron
run: yarn add @electron-forge/maker-dmg --dev
env:
HUSKY: '0'
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
ELECTRON_SKIP_BINARY_DOWNLOAD: '1'
SENTRYCLI_SKIP_DOWNLOAD: '1'

13
.github/actions/setup-sentry/action.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: Setup @sentry/cli
description: 'Setup @sentry/cli'
runs:
using: 'composite'
steps:
- name: 'Install @sentry/cli from brew'
if: runner.os == 'macos'
shell: bash
run: brew install getsentry/tools/sentry-cli
- name: 'Install @sentry/cli from npm'
if: runner.os != 'macos'
shell: bash
run: sudo npm install -g @sentry/cli --unsafe-perm

View File

@@ -47,6 +47,8 @@ jobs:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Setup @sentry/cli
uses: ./.github/actions/setup-sentry
- name: Get canary version
id: get-canary-version
if: ${{ github.ref_type == 'tag' }}
@@ -66,43 +68,32 @@ jobs:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
RELEASE_VERSION: ${{ github.event.inputs.version || steps.get-canary-version.outputs.RELEASE_VERSION }}
- name: Upload Artifact (web-static)
- name: Upload core artifact
uses: actions/upload-artifact@v3
with:
name: before-make-web-static
name: core
path: apps/electron/resources/web-static
make-distribution:
environment: production
strategy:
# all combinations: macos-latest x64, macos-latest arm64, windows-latest x64, ubuntu-latest x64
# all combinations: macos-latest x64, macos-latest arm64, ubuntu-latest x64
# For windows, we need a separate approach
matrix:
spec:
- {
os: macos-latest,
platform: darwin,
arch: x64,
target: x86_64-apple-darwin,
}
- {
os: macos-latest,
platform: darwin,
arch: arm64,
target: aarch64-apple-darwin,
}
- {
os: ubuntu-latest,
platform: linux,
arch: x64,
target: x86_64-unknown-linux-gnu,
}
- {
os: windows-latest,
platform: win32,
arch: x64,
target: x86_64-pc-windows-msvc,
}
runs-on: ${{ matrix.spec.os }}
- runner: macos-latest
platform: darwin
arch: x64
target: x86_64-apple-darwin
- runner: macos-latest
platform: darwin
arch: arm64
target: aarch64-apple-darwin
- runner: ubuntu-latest
platform: linux
arch: x64
target: x86_64-unknown-linux-gnu
runs-on: ${{ matrix.spec.runner }}
needs: before-make
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
@@ -112,7 +103,11 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
timeout-minutes: 10
uses: ./.github/actions/setup-node
- name: Setup Maker
timeout-minutes: 10
uses: ./.github/actions/setup-maker
- name: Build AFFiNE native
uses: ./.github/actions/build-rust
with:
@@ -120,7 +115,7 @@ jobs:
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
- uses: actions/download-artifact@v3
with:
name: before-make-web-static
name: core
path: apps/electron/resources/web-static
- name: Build Plugins
@@ -145,20 +140,170 @@ jobs:
mkdir -p builds
mv apps/electron/out/*/make/*.dmg ./builds/affine-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.dmg
mv apps/electron/out/*/make/zip/darwin/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ env.BUILD_TYPE }}-macos-${{ matrix.spec.arch }}.zip
- name: Save artifacts (windows)
if: ${{ matrix.spec.platform == 'win32' }}
run: |
mkdir -p builds
mv apps/electron/out/*/make/zip/win32/x64/AFFiNE*-win32-x64-*.zip ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.zip
mv apps/electron/out/*/make/squirrel.windows/x64/*.exe ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.exe
mv apps/electron/out/*/make/squirrel.windows/x64/*.msi ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.msi
mv apps/electron/out/*/make/squirrel.windows/x64/*.nupkg ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.nupkg
- name: Save artifacts (linux)
if: ${{ matrix.spec.platform == 'linux' }}
run: |
mkdir -p builds
mv apps/electron/out/*/make/zip/linux/x64/*.zip ./builds/affine-${{ env.BUILD_TYPE }}-linux-x64.zip
mv apps/electron/out/*/make/AppImage/x64/*.AppImage ./builds/affine-${{ env.BUILD_TYPE }}-linux-x64.AppImage
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: affine-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}-builds
path: builds
package-distribution-windows:
environment: production
strategy:
# all combinations: macos-latest x64, macos-latest arm64, ubuntu-latest x64
# For windows, we need a separate approach
matrix:
spec:
- runner: windows-latest
platform: win32
arch: x64
target: x86_64-pc-windows-msvc
runs-on: ${{ matrix.spec.runner }}
needs: before-make
outputs:
FILES_TO_BE_SIGNED: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED }}
env:
SKIP_GENERATE_ASSETS: 1
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
timeout-minutes: 10
uses: ./.github/actions/setup-node
- name: Setup Maker
timeout-minutes: 10
uses: ./.github/actions/setup-maker
- name: Build AFFiNE native
uses: ./.github/actions/build-rust
with:
target: ${{ matrix.spec.target }}
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
- uses: actions/download-artifact@v3
with:
name: core
path: apps/electron/resources/web-static
- name: Build Plugins
run: yarn run build:plugins
- name: Build Desktop Layers
run: yarn workspace @affine/electron build
- name: package
run: yarn workspace @affine/electron package --platform=${{ matrix.spec.platform }} --arch=${{ matrix.spec.arch }}
- name: get all files to be signed
id: get_files_to_be_signed
run: |
Set-Variable -Name FILES_TO_BE_SIGNED -Value ((Get-ChildItem -Path apps/electron/out -Recurse -File | Where-Object { $_.Extension -in @(".exe", ".node", ".dll", ".msi") } | ForEach-Object { '"' + $_.FullName.Replace((Get-Location).Path + '\apps\electron\out\', '') + '"' }) -join ' ')
"FILES_TO_BE_SIGNED=$FILES_TO_BE_SIGNED" >> $env:GITHUB_OUTPUT
echo $FILES_TO_BE_SIGNED
- name: Zip artifacts for faster upload
run: Compress-Archive -CompressionLevel Fastest -Path apps/electron/out/* -DestinationPath archive.zip
- name: Save packaged artifacts for signing
uses: actions/upload-artifact@v3
with:
name: packaged-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
path: |
archive.zip
!**/*.map
sign-packaged-artifacts-windows:
needs: package-distribution-windows
uses: ./.github/workflows/windows-signer.yml
with:
files: ${{ needs.package-distribution-windows.outputs.FILES_TO_BE_SIGNED }}
artifact-name: packaged-win32-x64
make-windows-installer:
environment: production
needs: sign-packaged-artifacts-windows
strategy:
# all combinations: macos-latest x64, macos-latest arm64, ubuntu-latest x64
# For windows, we need a separate approach
matrix:
spec:
- runner: windows-latest
platform: win32
arch: x64
target: x86_64-pc-windows-msvc
runs-on: ${{ matrix.spec.runner }}
outputs:
FILES_TO_BE_SIGNED: ${{ steps.get_files_to_be_signed.outputs.FILES_TO_BE_SIGNED }}
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
timeout-minutes: 10
uses: ./.github/actions/setup-node
- name: Download and overwrite packaged artifacts
uses: actions/download-artifact@v3
with:
name: signed-packaged-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
path: .
- name: unzip file
run: Expand-Archive -Path signed.zip -DestinationPath apps/electron/out
- name: Make squirrel.windows installer
run: yarn workspace @affine/electron make-squirrel --platform=${{ matrix.spec.platform }} --arch=${{ matrix.spec.arch }}
- name: Zip artifacts for faster upload
run: Compress-Archive -CompressionLevel Fastest -Path apps/electron/out/${{ env.BUILD_TYPE }}/make/* -DestinationPath archive.zip
- name: get all files to be signed
id: get_files_to_be_signed
run: |
Set-Variable -Name FILES_TO_BE_SIGNED -Value ((Get-ChildItem -Path apps/electron/out/${{ env.BUILD_TYPE }}/make -Recurse -File | Where-Object { $_.Extension -in @(".exe", ".node", ".dll", ".msi") } | ForEach-Object { '"' + $_.FullName.Replace((Get-Location).Path + '\apps\electron\out\${{ env.BUILD_TYPE }}\make\', '') + '"' }) -join ' ')
"FILES_TO_BE_SIGNED=$FILES_TO_BE_SIGNED" >> $env:GITHUB_OUTPUT
echo $FILES_TO_BE_SIGNED
- name: Save installer for signing
uses: actions/upload-artifact@v3
with:
name: installer-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
path: archive.zip
sign-installer-artifacts-windows:
needs: make-windows-installer
uses: ./.github/workflows/windows-signer.yml
with:
files: ${{ needs.make-windows-installer.outputs.FILES_TO_BE_SIGNED }}
artifact-name: installer-win32-x64
finalize-installer-windows:
environment: production
needs: sign-installer-artifacts-windows
strategy:
# all combinations: macos-latest x64, macos-latest arm64, ubuntu-latest x64
# For windows, we need a separate approach
matrix:
spec:
- runner: windows-latest
platform: win32
arch: x64
target: x86_64-pc-windows-msvc
runs-on: ${{ matrix.spec.runner }}
steps:
- name: Download and overwrite installer artifacts
uses: actions/download-artifact@v3
with:
name: signed-installer-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
path: .
- name: unzip file
run: Expand-Archive -Path signed.zip -DestinationPath apps/electron/out/${{ env.BUILD_TYPE }}/make
- name: Save artifacts
run: |
mkdir -p builds
mv apps/electron/out/*/make/zip/win32/x64/AFFiNE*-win32-x64-*.zip ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.zip
mv apps/electron/out/*/make/squirrel.windows/x64/*.exe ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.exe
mv apps/electron/out/*/make/squirrel.windows/x64/*.msi ./builds/affine-${{ env.BUILD_TYPE }}-windows-x64.msi
- name: Upload Artifact
uses: actions/upload-artifact@v3
@@ -167,7 +312,7 @@ jobs:
path: builds
release:
needs: [before-make, make-distribution]
needs: [before-make, make-distribution, finalize-installer-windows]
runs-on: ubuntu-latest
steps:
@@ -215,7 +360,6 @@ jobs:
./*.zip
./*.dmg
./*.exe
./*.nupkg
./RELEASES
./*.AppImage
./*.apk

42
.github/workflows/windows-signer.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: Windows Signer
on:
workflow_call:
inputs:
artifact-name:
required: true
type: string
files:
required: true
type: string
jobs:
sign:
runs-on: [self-hosted, win-signer]
env:
ARCHIVE_DIR: ${{ github.run_id }}-${{ github.run_attempt }}-${{ inputs.artifact-name }}
steps:
- uses: actions/download-artifact@v3
with:
name: ${{ inputs.artifact-name }}
path: ${{ env.ARCHIVE_DIR }}
- name: unzip file
shell: cmd
# 7za is pre-installed on the signer machine
run: |
cd ${{ env.ARCHIVE_DIR }}
md out
7za x archive.zip -y -oout
- name: sign
shell: cmd
run: |
cd ${{ env.ARCHIVE_DIR }}/out
signtool sign /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a ${{ inputs.files }}
- name: zip file
shell: cmd
run: |
cd ${{ env.ARCHIVE_DIR }}
7za a signed.zip .\out\*
- name: upload
uses: actions/upload-artifact@v3
with:
name: signed-${{ inputs.artifact-name }}
path: ${{ env.ARCHIVE_DIR }}/signed.zip

View File

@@ -1,6 +1,6 @@
{
"name": "@affine/docs",
"version": "0.7.0-beta.1",
"version": "0.7.3",
"type": "module",
"private": true,
"scripts": {

View File

@@ -1,32 +1,89 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const { z } = require('zod');
const {
utils: { fromBuildIdentifier },
} = require('@electron-forge/core');
const path = require('node:path');
const ReleaseTypeSchema = z.enum(['stable', 'beta', 'canary', 'internal']);
const {
arch,
buildType,
icnsPath,
icoPath,
platform,
productName,
iconUrl,
} = require('./scripts/make-env');
const envBuildType = (process.env.BUILD_TYPE || 'canary').trim().toLowerCase();
const buildType = ReleaseTypeSchema.parse(envBuildType);
const stableBuild = buildType === 'stable';
const productName = !stableBuild ? `AFFiNE-${buildType}` : 'AFFiNE';
const icoPath = !stableBuild
? `./resources/icons/icon_${buildType}.ico`
: './resources/icons/icon.ico';
const icnsPath = !stableBuild
? `./resources/icons/icon_${buildType}.icns`
: './resources/icons/icon.icns';
const arch =
process.argv.indexOf('--arch') > 0
? process.argv[process.argv.indexOf('--arch') + 1]
: process.arch;
const windowsIconUrl = `https://cdn.affine.pro/app-icons/icon_${buildType}.ico`;
const makers = [
!process.env.SKIP_BUNDLE &&
platform === 'darwin' && {
name: '@electron-forge/maker-dmg',
config: {
format: 'ULFO',
icon: icnsPath,
name: 'AFFiNE',
'icon-size': 128,
background: path.resolve(
__dirname,
'./resources/icons/dmg-background.png'
),
contents: [
{
x: 176,
y: 192,
type: 'file',
path: path.resolve(
__dirname,
'out',
buildType,
`${productName}-darwin-${arch}`,
`${productName}.app`
),
},
{ x: 432, y: 192, type: 'link', path: '/Applications' },
],
file: path.resolve(
__dirname,
'out',
buildType,
`${productName}-darwin-${arch}`,
`${productName}.app`
),
},
},
{
name: '@electron-forge/maker-zip',
config: {
name: 'affine',
iconUrl: icoPath,
setupIcon: icoPath,
platforms: ['darwin', 'linux', 'win32'],
},
},
!process.env.SKIP_BUNDLE && {
name: '@electron-forge/maker-squirrel',
config: {
name: productName,
setupIcon: icoPath,
iconUrl: iconUrl,
loadingGif: './resources/icons/affine_installing.gif',
},
},
!process.env.SKIP_BUNDLE && {
name: '@reforged/maker-appimage',
config: {
name: 'AFFiNE',
iconUrl: icoPath,
setupIcon: icoPath,
platforms: ['linux'],
options: {
bin: productName,
},
},
},
].filter(Boolean);
/**
* @type {import('@electron-forge/shared-types').ForgeConfig}
@@ -56,52 +113,9 @@ module.exports = {
: undefined,
// We need the following line for updater
extraResource: ['./resources/app-update.yml'],
ignore: ['e2e', 'tests'],
},
makers: [
{
name: '@electron-forge/maker-dmg',
config: {
format: 'ULFO',
icon: icnsPath,
name: 'AFFiNE',
'icon-size': 128,
background: './resources/icons/dmg-background.png',
contents: [
{
x: 176,
y: 192,
type: 'file',
path: path.resolve(
__dirname,
'out',
buildType,
`${productName}-darwin-${arch}`,
`${productName}.app`
),
},
{ x: 432, y: 192, type: 'link', path: '/Applications' },
],
},
},
{
name: '@electron-forge/maker-zip',
config: {
name: 'affine',
iconUrl: icoPath,
setupIcon: icoPath,
platforms: ['darwin', 'linux', 'win32'],
},
},
{
name: '@electron-forge/maker-squirrel',
config: {
name: 'AFFiNE',
setupIcon: icoPath,
iconUrl: windowsIconUrl,
loadingGif: './resources/icons/affine_installing.gif',
},
},
],
makers,
hooks: {
readPackageJson: async (_, packageJson) => {
// we want different package name for canary build

View File

@@ -1,7 +1,7 @@
{
"name": "@affine/electron",
"private": true,
"version": "0.7.0-beta.1",
"version": "0.7.3",
"author": "affine",
"repository": {
"url": "https://github.com/toeverything/AFFiNE",
@@ -16,7 +16,8 @@
"generate-assets": "zx scripts/generate-assets.mjs",
"package": "electron-forge package",
"make": "electron-forge make",
"test": "DEBUG=pw:browser yarn -T run playwright test -c ./playwright.config.ts"
"test": "DEBUG=pw:browser yarn -T run playwright test -c ./playwright.config.ts",
"make-squirrel": "yarn ts-node-esm -T scripts/make-squirrel.mts"
},
"config": {
"forge": "./forge.config.js"
@@ -39,6 +40,7 @@
"@electron-forge/maker-zip": "^6.2.1",
"@electron-forge/shared-types": "^6.2.1",
"@electron/remote": "2.0.10",
"@reforged/maker-appimage": "^3.3.1",
"@toeverything/infra": "workspace:*",
"@types/fs-extra": "^11.0.1",
"@types/uuid": "^9.0.2",
@@ -64,7 +66,7 @@
"lodash-es": "^4.17.21",
"nanoid": "^4.0.2",
"rxjs": "^7.8.1",
"yjs": "^13.6.6"
"yjs": "^13.6.7"
},
"build": {
"protocols": [

View File

@@ -1,5 +1,5 @@
import { fileURLToPath } from 'node:url';
import { readdir } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
const outputRoot = fileURLToPath(
new URL(

View File

@@ -0,0 +1,49 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const { z } = require('zod');
const path = require('node:path');
const ReleaseTypeSchema = z.enum(['stable', 'beta', 'canary', 'internal']);
const ROOT = path.resolve(__dirname, '..');
const envBuildType = (process.env.BUILD_TYPE || 'canary').trim().toLowerCase();
const buildType = ReleaseTypeSchema.parse(envBuildType);
const stableBuild = buildType === 'stable';
const productName = !stableBuild ? `AFFiNE-${buildType}` : 'AFFiNE';
const icoPath = path.join(
ROOT,
!stableBuild
? `./resources/icons/icon_${buildType}.ico`
: './resources/icons/icon.ico'
);
const icnsPath = path.join(
ROOT,
!stableBuild
? `./resources/icons/icon_${buildType}.icns`
: './resources/icons/icon.icns'
);
const iconUrl = `https://cdn.affine.pro/app-icons/icon_${buildType}.ico`;
const arch =
process.argv.indexOf('--arch') > 0
? process.argv[process.argv.indexOf('--arch') + 1]
: process.arch;
const platform =
process.argv.indexOf('--platform') > 0
? process.argv[process.argv.indexOf('--platform') + 1]
: process.platform;
module.exports = {
ROOT,
buildType,
productName,
icoPath,
icnsPath,
iconUrl,
arch,
platform,
stableBuild,
};

View File

@@ -0,0 +1,82 @@
import type { Options as ElectronWinstallerOptions } from 'electron-winstaller';
import { convertVersion, createWindowsInstaller } from 'electron-winstaller';
import fs from 'fs-extra';
import path from 'path';
import {
arch,
buildType,
iconUrl,
platform,
productName,
ROOT,
} from './make-env';
async function ensureDirectory(dir: string) {
if (await fs.pathExists(dir)) {
await fs.remove(dir);
}
return fs.mkdirs(dir);
}
// taking from https://github.com/electron/forge/blob/main/packages/maker/squirrel/src/MakerSquirrel.ts
// it was for forge's maker, but can be used standalone as well
async function make() {
const appName = productName;
const makeDir = path.resolve(ROOT, 'out', buildType, 'make');
const outPath = path.resolve(makeDir, `squirrel.windows/${arch}`);
const appDirectory = path.resolve(
ROOT,
'out',
buildType,
`${appName}-${platform}-${arch}`
);
await ensureDirectory(outPath);
const packageJSON = await fs.readJson(path.resolve(ROOT, 'package.json'));
const winstallerConfig: ElectronWinstallerOptions = {
name: appName,
title: appName,
noMsi: true,
exe: `${appName}.exe`,
setupExe: `${appName}-${packageJSON.version} Setup.exe`,
version: packageJSON.version,
appDirectory: appDirectory,
outputDirectory: outPath,
iconUrl: iconUrl,
loadingGif: path.resolve(ROOT, './resources/icons/affine_installing.gif'),
};
await createWindowsInstaller(winstallerConfig);
const nupkgVersion = convertVersion(packageJSON.version);
const artifacts = [
path.resolve(outPath, 'RELEASES'),
path.resolve(outPath, winstallerConfig.setupExe || `${appName}Setup.exe`),
path.resolve(
outPath,
`${winstallerConfig.name}-${nupkgVersion}-full.nupkg`
),
];
const deltaPath = path.resolve(
outPath,
`${winstallerConfig.name}-${nupkgVersion}-delta.nupkg`
);
if (
(winstallerConfig.remoteReleases && !winstallerConfig.noDelta) ||
(await fs.pathExists(deltaPath))
) {
artifacts.push(deltaPath);
}
const msiPath = path.resolve(
outPath,
winstallerConfig.setupMsi || `${appName}Setup.msi`
);
if (!winstallerConfig.noMsi && (await fs.pathExists(msiPath))) {
artifacts.push(msiPath);
}
console.log('making squirrel.windows done:', artifacts);
return artifacts;
}
make();

View File

@@ -8,7 +8,8 @@
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true,
"noEmit": false,
"outDir": "./lib/scripts"
"outDir": "./lib/scripts",
"allowJs": true
},
"include": ["./scripts", "esbuild.main.config.ts", "esbuild.plugin.config.ts"]
}

View File

@@ -1,7 +1,7 @@
{
"name": "@affine/server",
"private": true,
"version": "0.7.0-beta.1",
"version": "0.7.3",
"description": "Affine Node.js server",
"type": "module",
"bin": {

View File

@@ -48,5 +48,5 @@
"@blocksuite/lit": "*",
"@blocksuite/store": "*"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -1,7 +1,7 @@
{
"name": "@affine/web",
"private": true,
"version": "0.7.0-beta.1",
"version": "0.7.3",
"scripts": {
"dev": "next dev",
"build": "next build && next export",
@@ -54,7 +54,7 @@
"rxjs": "^7.8.1",
"swr": "^2.1.5",
"y-protocols": "^1.0.5",
"yjs": "^13.6.6",
"yjs": "^13.6.7",
"zod": "^3.21.4"
},
"devDependencies": {

View File

@@ -23,7 +23,7 @@ const buildPreset = {
enableTestProperties: false,
enableBroadcastChannelProvider: true,
enableDebugPage: true,
changelogUrl: 'https://affine.pro/blog/what-is-new-affine-0717',
changelogUrl: 'https://affine.pro/blog/what-is-new-affine-0728',
imageProxyUrl: 'https://workers.toeverything.workers.dev/proxy/image',
enablePreloading: true,
enableNewSettingModal: true,
@@ -41,7 +41,7 @@ const buildPreset = {
enableTestProperties: true,
enableBroadcastChannelProvider: true,
enableDebugPage: true,
changelogUrl: 'https://affine.pro/blog/what-is-new-affine-0717',
changelogUrl: 'https://affine.pro/blog/what-is-new-affine-0728',
imageProxyUrl: 'https://workers.toeverything.workers.dev/proxy/image',
enablePreloading: true,
enableNewSettingModal: true,

View File

@@ -1,6 +1,6 @@
{
"name": "@affine/monorepo",
"version": "0.7.0-beta.1",
"version": "0.7.3",
"private": true,
"author": "toeverything",
"license": "MPL-2.0",

View File

@@ -19,5 +19,5 @@
"peerDependencies": {
"ts-node": "*"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -64,7 +64,7 @@
"@vanilla-extract/css": "^1.12.0",
"typescript": "^5.1.6",
"vite": "^4.3.9",
"yjs": "^13.6.6"
"yjs": "^13.6.7"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -8,5 +8,5 @@
"devDependencies": {
"@types/debug": "^4.1.8"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -27,5 +27,5 @@
"dependencies": {
"lit": "^2.7.5"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@affine/graphql",
"version": "0.7.0-beta.1",
"version": "0.7.3",
"description": "Autogenerated GraphQL client for affine.pro",
"license": "MPL-2.0",
"type": "module",

View File

@@ -8,5 +8,5 @@
"@affine/env": "workspace:*",
"@toeverything/y-indexeddb": "workspace:*"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -37,5 +37,5 @@
"ts-node": "^10.9.1",
"typescript": "^5.1.6"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -46,5 +46,5 @@
"optional": true
}
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -21,5 +21,5 @@
"@blocksuite/store": "*",
"lottie-web": "*"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -38,5 +38,5 @@
"test": "cross-env TS_NODE_TRANSPILE_ONLY=1 TS_NODE_PROJECT=./tsconfig.json node --test --loader ts-node/esm --experimental-specifier-resolution=node ./__tests__/**/*.mts",
"version": "napi version"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -49,5 +49,5 @@
"react": "*",
"react-dom": "*"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@affine/storage",
"version": "0.7.0-beta.1",
"version": "0.7.3",
"engines": {
"node": ">= 10.16.0 < 11 || >= 11.8.0"
},
@@ -37,7 +37,7 @@
},
"devDependencies": {
"@napi-rs/cli": "^3.0.0-alpha.4",
"lib0": "^0.2.78",
"yjs": "^13.6.6"
"lib0": "^0.2.80",
"yjs": "^13.6.7"
}
}

View File

@@ -6,5 +6,5 @@
"./*.md": "./*.md",
"./preloading.json": "./preloading.json"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -24,11 +24,11 @@
"jotai": "^2.2.2",
"js-base64": "^3.7.5",
"ky": "^0.33.3",
"lib0": "^0.2.78",
"lib0": "^0.2.80",
"react": "18.2.0",
"react-dom": "18.2.0",
"y-protocols": "^1.0.5",
"yjs": "^13.6.6",
"yjs": "^13.6.7",
"zod": "^3.21.4"
},
"devDependencies": {
@@ -36,5 +36,5 @@
"next": "=13.4.2",
"ws": "^8.13.0"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -81,9 +81,30 @@ const rootWorkspacesMetadataPromiseAtom = atom<
// fixme(himself65): we might not need step 1
// step 1: try load metadata from localStorage
{
const loadFromLocalStorage = (): RootWorkspaceMetadata[] => {
// don't change this key,
// otherwise it will cause the data loss in the production
const primitiveMetadata = localStorage.getItem(METADATA_STORAGE_KEY);
if (primitiveMetadata) {
try {
const items = JSON.parse(primitiveMetadata) as z.infer<
typeof rootWorkspaceMetadataArraySchema
>;
rootWorkspaceMetadataArraySchema.parse(items);
return [...items];
} catch (e) {
console.error('cannot parse worksapce', e);
}
return [];
}
return [];
};
const maybeMetadata = loadFromLocalStorage();
// migration step, only data in `METADATA_STORAGE_KEY` will be migrated
if (
metadata.some(meta => !('version' in meta)) &&
maybeMetadata.some(meta => !('version' in meta)) &&
!globalThis.$migrationDone
) {
await new Promise<void>((resolve, reject) => {
@@ -94,20 +115,7 @@ const rootWorkspacesMetadataPromiseAtom = atom<
});
}
// don't change this key,
// otherwise it will cause the data loss in the production
const primitiveMetadata = localStorage.getItem(METADATA_STORAGE_KEY);
if (primitiveMetadata) {
try {
const items = JSON.parse(primitiveMetadata) as z.infer<
typeof rootWorkspaceMetadataArraySchema
>;
rootWorkspaceMetadataArraySchema.parse(items);
metadata.push(...items);
} catch (e) {
console.error('cannot parse worksapce', e);
}
}
metadata.push(...loadFromLocalStorage());
}
// step 2: fetch from adapters
{

View File

@@ -9,7 +9,7 @@ import { Workspace } from '@blocksuite/store';
import { createBroadcastChannelProvider } from '@blocksuite/store/providers/broadcast-channel';
import {
createIndexedDBProvider as create,
downloadBinary,
downloadBinaries,
EarlyDisconnectError,
} from '@toeverything/y-indexeddb';
import type { Doc } from 'yjs';
@@ -61,7 +61,7 @@ const createIndexedDBBackgroundProvider: DocProviderCreator = (
};
};
const cache: WeakMap<Doc, Uint8Array> = new WeakMap();
const cache: WeakMap<Doc, Uint8Array[]> = new WeakMap();
const createIndexedDBDownloadProvider: DocProviderCreator = (
id,
@@ -75,15 +75,20 @@ const createIndexedDBDownloadProvider: DocProviderCreator = (
});
async function downloadBinaryRecursively(doc: Doc) {
if (cache.has(doc)) {
const binary = cache.get(doc) as Uint8Array;
Y.applyUpdate(doc, binary);
} else {
const binary = await downloadBinary(doc.guid);
if (binary) {
const binaries = cache.get(doc) as Uint8Array[];
binaries.forEach(binary => {
Y.applyUpdate(doc, binary);
cache.set(doc, binary);
}
});
return;
}
const binaries = await downloadBinaries(doc.guid);
if (!binaries) {
return;
}
cache.set(doc, binaries);
binaries.forEach(binary => {
Y.applyUpdate(doc, binary);
});
await Promise.all([...doc.subdocs].map(downloadBinaryRecursively));
}
return {

View File

@@ -1,7 +1,7 @@
{
"name": "@toeverything/y-indexeddb",
"type": "module",
"version": "0.7.0-beta.1",
"version": "0.7.3",
"description": "IndexedDB database adapter for Yjs",
"repository": "toeverything/AFFiNE",
"author": "toeverything",

View File

@@ -144,6 +144,23 @@ export async function downloadBinary(
}
}
export async function downloadBinaries(
guid: string,
dbName = DEFAULT_DB_NAME
): Promise<UpdateMessage['update'][] | false> {
const dbPromise = openDB<BlockSuiteBinaryDB>(dbName, dbVersion, {
upgrade: upgradeDB,
});
const db = await dbPromise;
const t = db.transaction('workspace', 'readonly').objectStore('workspace');
const doc = await t.get(guid);
if (!doc) {
return false;
} else {
return doc.updates.map(({ update }) => update);
}
}
export async function overwriteBinary(
guid: string,
update: UpdateMessage['update'],

View File

@@ -25,5 +25,5 @@
"react": "*",
"react-dom": "*"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -28,5 +28,5 @@
"react": "*",
"react-dom": "*"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -84,8 +84,6 @@ test('init page', async ({ page, context }) => {
await switchToNext();
await page.waitForTimeout(1000);
await page.goto('http://localhost:8081/');
await page.waitForTimeout(1000);
await page.goto('http://localhost:8081/');
await page.waitForSelector('v-line', {
timeout: 10000,
});

View File

@@ -21,5 +21,5 @@
"serve": "^14.2.0",
"vitest": "^0.32.2"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -9,5 +9,5 @@
"@affine-test/kit": "workspace:*",
"@playwright/test": "^1.35.1"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -3,5 +3,5 @@
"exports": {
"./*": "./*"
},
"version": "0.7.0-beta.1"
"version": "0.7.3"
}

View File

@@ -1,7 +1,7 @@
{
"name": "@affine-test/kit",
"private": true,
"version": "0.7.0-beta.1",
"version": "0.7.3",
"exports": {
"./playwright": "./playwright.ts",
"./utils/*": "./utils/*.ts"

156
yarn.lock
View File

@@ -145,7 +145,7 @@ __metadata:
rxjs: ^7.8.1
typescript: ^5.1.6
vite: ^4.3.9
yjs: ^13.6.6
yjs: ^13.6.7
peerDependencies:
"@blocksuite/blocks": "*"
"@blocksuite/editor": "*"
@@ -236,6 +236,7 @@ __metadata:
"@electron-forge/maker-zip": ^6.2.1
"@electron-forge/shared-types": ^6.2.1
"@electron/remote": 2.0.10
"@reforged/maker-appimage": ^3.3.1
"@toeverything/infra": "workspace:*"
"@toeverything/plugin-infra": "workspace:*"
"@types/fs-extra": ^11.0.1
@@ -258,7 +259,7 @@ __metadata:
undici: ^5.22.1
uuid: ^9.0.0
which: ^3.0.1
yjs: ^13.6.6
yjs: ^13.6.7
zx: ^7.2.2
peerDependencies:
ts-node: "*"
@@ -461,8 +462,8 @@ __metadata:
resolution: "@affine/storage@workspace:packages/storage"
dependencies:
"@napi-rs/cli": ^3.0.0-alpha.4
lib0: ^0.2.78
yjs: ^13.6.6
lib0: ^0.2.80
yjs: ^13.6.7
languageName: unknown
linkType: soft
@@ -590,7 +591,7 @@ __metadata:
typescript: ^5.1.6
webpack: ^5.88.1
y-protocols: ^1.0.5
yjs: ^13.6.6
yjs: ^13.6.7
zod: ^3.21.4
languageName: unknown
linkType: soft
@@ -610,13 +611,13 @@ __metadata:
jotai: ^2.2.2
js-base64: ^3.7.5
ky: ^0.33.3
lib0: ^0.2.78
lib0: ^0.2.80
next: =13.4.2
react: 18.2.0
react-dom: 18.2.0
ws: ^8.13.0
y-protocols: ^1.0.5
yjs: ^13.6.6
yjs: ^13.6.7
zod: ^3.21.4
peerDependencies:
"@blocksuite/blocks": "*"
@@ -4087,6 +4088,17 @@ __metadata:
languageName: node
linkType: hard
"@electron-forge/maker-base@npm:^6.0.4":
version: 6.4.1
resolution: "@electron-forge/maker-base@npm:6.4.1"
dependencies:
"@electron-forge/shared-types": 6.4.1
fs-extra: ^10.0.0
which: ^2.0.2
checksum: 30b798cf3be3d84e3756ffe9c714e1529e6ddd27eaff74fc1470abe5671f9226480d352fa2c391cc9e7b0b07f4824fdd567268c1551e9319e83c054f917918f4
languageName: node
linkType: hard
"@electron-forge/maker-deb@npm:^6.2.1":
version: 6.2.1
resolution: "@electron-forge/maker-deb@npm:6.2.1"
@@ -4173,6 +4185,17 @@ __metadata:
languageName: node
linkType: hard
"@electron-forge/shared-types@npm:6.4.1":
version: 6.4.1
resolution: "@electron-forge/shared-types@npm:6.4.1"
dependencies:
"@electron/rebuild": ^3.2.10
electron-packager: ^17.1.2
listr2: ^5.0.3
checksum: 0a629d559e4968f9bbcdf086850449194bb09f051dfd272644a0979f871de611b066da4936a0841e6f3d6b21d6487c5b3ee27fffadea055cec13926e8d89658f
languageName: node
linkType: hard
"@electron-forge/template-base@npm:6.2.1":
version: 6.2.1
resolution: "@electron-forge/template-base@npm:6.2.1"
@@ -4279,6 +4302,23 @@ __metadata:
languageName: node
linkType: hard
"@electron/osx-sign@npm:^1.0.5":
version: 1.0.5
resolution: "@electron/osx-sign@npm:1.0.5"
dependencies:
compare-version: ^0.1.2
debug: ^4.3.4
fs-extra: ^10.0.0
isbinaryfile: ^4.0.8
minimist: ^1.2.6
plist: ^3.0.5
bin:
electron-osx-flat: bin/electron-osx-flat.js
electron-osx-sign: bin/electron-osx-sign.js
checksum: 6c662e8bb4322b83f0147ddb4f5815770aca980a2cefc58a8423d502ccee4428168e11fa3c50f9660d29a74e3397f96c4f6ebddf1695ed28366aac0b92a49029
languageName: node
linkType: hard
"@electron/rebuild@npm:^3.2.10":
version: 3.2.13
resolution: "@electron/rebuild@npm:3.2.13"
@@ -8875,6 +8915,18 @@ __metadata:
languageName: node
linkType: hard
"@reforged/maker-appimage@npm:^3.3.1":
version: 3.3.1
resolution: "@reforged/maker-appimage@npm:3.3.1"
dependencies:
"@electron-forge/maker-base": ^6.0.4
"@spacingbat3/lss": ^1.0.0
node-fetch: ^3.2.5
semver: ^7.3.8
checksum: 9761c4eaf73df9ab6eca0b002d4967856185fbbec1dd423439eff2c62aa1da6befd9d4161cb4f9a219acbddca9da8a576f4a40bce4231b6de7dd431d94f81168
languageName: node
linkType: hard
"@repeaterjs/repeater@npm:3.0.4, @repeaterjs/repeater@npm:^3.0.4":
version: 3.0.4
resolution: "@repeaterjs/repeater@npm:3.0.4"
@@ -9693,6 +9745,13 @@ __metadata:
languageName: node
linkType: hard
"@spacingbat3/lss@npm:^1.0.0":
version: 1.2.0
resolution: "@spacingbat3/lss@npm:1.2.0"
checksum: 7fa48f95e94c6a763a4c886eda65f964ad1a39bb5e3e3c439ab6ce4794b4712724badef90f16115707b2a74b066856eb3825f2510d5adaa9b7aa2d4f22d6f2b2
languageName: node
linkType: hard
"@storybook/addon-actions@npm:7.0.24, @storybook/addon-actions@npm:^7.0.24":
version: 7.0.24
resolution: "@storybook/addon-actions@npm:7.0.24"
@@ -16870,6 +16929,35 @@ __metadata:
languageName: node
linkType: hard
"electron-packager@npm:^17.1.2":
version: 17.1.2
resolution: "electron-packager@npm:17.1.2"
dependencies:
"@electron/asar": ^3.2.1
"@electron/get": ^2.0.0
"@electron/notarize": ^1.2.3
"@electron/osx-sign": ^1.0.5
"@electron/universal": ^1.3.2
cross-spawn-windows-exe: ^1.2.0
debug: ^4.0.1
extract-zip: ^2.0.0
filenamify: ^4.1.0
fs-extra: ^11.1.0
galactus: ^1.0.0
get-package-info: ^1.0.0
junk: ^3.1.0
parse-author: ^2.0.0
plist: ^3.0.0
rcedit: ^3.0.1
resolve: ^1.1.6
semver: ^7.1.3
yargs-parser: ^21.1.1
bin:
electron-packager: bin/electron-packager.js
checksum: ce65f120084d1562a6534d1f594e2be21d13cf24dfd58f2651cf6fc519f3d2a25fa32743ed17a4fe53f096aafe0e920ae90cb20afb3a1841cf52a6a86a80a6db
languageName: node
linkType: hard
"electron-squirrel-startup@npm:1.0.0":
version: 1.0.0
resolution: "electron-squirrel-startup@npm:1.0.0"
@@ -18699,6 +18787,16 @@ __metadata:
languageName: node
linkType: hard
"flora-colossus@npm:^2.0.0":
version: 2.0.0
resolution: "flora-colossus@npm:2.0.0"
dependencies:
debug: ^4.3.4
fs-extra: ^10.1.0
checksum: b31b30697de4969e97201f1b17353c533430d1606911c4d3e4f7f6dafda4a62f50c4ddf99fdd2f6f6313666a572e83c0831302a3e25c997a5679998b440d6265
languageName: node
linkType: hard
"flow-parser@npm:0.*":
version: 0.209.0
resolution: "flow-parser@npm:0.209.0"
@@ -19074,6 +19172,17 @@ __metadata:
languageName: node
linkType: hard
"galactus@npm:^1.0.0":
version: 1.0.0
resolution: "galactus@npm:1.0.0"
dependencies:
debug: ^4.3.4
flora-colossus: ^2.0.0
fs-extra: ^10.1.0
checksum: f7a3bd16c8bd5304e27b0e631defb8750ab8a9676c4fc754ec48f97f8d56b0841850372d9bf9932bd77833d16225c81dedb0e7366ccd82c11c2bd5cc41644493
languageName: node
linkType: hard
"gar@npm:^1.0.4":
version: 1.0.4
resolution: "gar@npm:1.0.4"
@@ -22707,7 +22816,7 @@ __metadata:
languageName: node
linkType: hard
"lib0@npm:^0.2.42, lib0@npm:^0.2.74, lib0@npm:^0.2.78":
"lib0@npm:^0.2.42, lib0@npm:^0.2.74":
version: 0.2.78
resolution: "lib0@npm:0.2.78"
dependencies:
@@ -22719,6 +22828,18 @@ __metadata:
languageName: node
linkType: hard
"lib0@npm:^0.2.80":
version: 0.2.80
resolution: "lib0@npm:0.2.80"
dependencies:
isomorphic.js: ^0.2.4
bin:
0gentesthtml: bin/gentesthtml.js
0serve: bin/0serve.js
checksum: eddb9c6cc23a916e3f6c26b3e729882c1f886de138b2de4055fb51a941acd7dab08eb65c9b9b43f01a5c83e0936169010e0c6e517d30446540019eebcb1ef6f6
languageName: node
linkType: hard
"lie@npm:3.1.1":
version: 3.1.1
resolution: "lie@npm:3.1.1"
@@ -24422,6 +24543,17 @@ __metadata:
languageName: node
linkType: hard
"node-fetch@npm:^3.2.5":
version: 3.3.2
resolution: "node-fetch@npm:3.3.2"
dependencies:
data-uri-to-buffer: ^4.0.0
fetch-blob: ^3.1.4
formdata-polyfill: ^4.0.10
checksum: 06a04095a2ddf05b0830a0d5302699704d59bda3102894ea64c7b9d4c865ecdff2d90fd042df7f5bc40337266961cb6183dcc808ea4f3000d024f422b462da92
languageName: node
linkType: hard
"node-gyp-build@npm:^4.3.0":
version: 4.6.0
resolution: "node-gyp-build@npm:4.6.0"
@@ -31509,12 +31641,12 @@ __metadata:
languageName: node
linkType: hard
"yjs@npm:^13.6.6":
version: 13.6.6
resolution: "yjs@npm:13.6.6"
"yjs@npm:^13.6.7":
version: 13.6.7
resolution: "yjs@npm:13.6.7"
dependencies:
lib0: ^0.2.74
checksum: c69cb9a084aa433e813f6d0a191ebad5800a9a7098f7c6715952e4f8e5fc23270e3b8d7d747e1b0d0f1adca5f6efe01019654389eddb3977006814c4e2ff7ce6
checksum: 8e89257c8b565ab97cf3354fca2ce0b6bc3d1abe90b9d45a218a94b35da372c88d2411b353ed8ca03a6619004c4da76c96f7c203c38506c3758c9f8c1a730ca4
languageName: node
linkType: hard