From 13e712158cb90cad1240a8e4b63639efe55ce91e Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Sat, 25 Nov 2023 22:59:47 +0800 Subject: [PATCH 01/11] feat: optional payment for server (#5055) --- packages/backend/server/src/modules/config.ts | 30 +++++++++++++++++++ packages/backend/server/src/modules/index.ts | 20 +++++++++---- packages/backend/server/src/schema.gql | 11 +++++++ .../frontend/graphql/src/graphql/index.ts | 14 +++++++++ .../graphql/src/graphql/server-config.gql | 6 ++++ packages/frontend/graphql/src/schema.ts | 16 ++++++++++ 6 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 packages/backend/server/src/modules/config.ts create mode 100644 packages/frontend/graphql/src/graphql/server-config.gql diff --git a/packages/backend/server/src/modules/config.ts b/packages/backend/server/src/modules/config.ts new file mode 100644 index 0000000000..d0fb9e69d4 --- /dev/null +++ b/packages/backend/server/src/modules/config.ts @@ -0,0 +1,30 @@ +import { Module } from '@nestjs/common'; +import { Field, ObjectType, Query } from '@nestjs/graphql'; + +import { SERVER_FLAVOR } from '../modules'; + +@ObjectType() +export class ServerConfigType { + @Field({ description: 'server version' }) + version!: string; + + @Field({ description: 'server flavor' }) + flavor!: string; +} + +export class ServerConfigResolver { + @Query(() => ServerConfigType, { + description: 'server config', + }) + serverConfig(): ServerConfigType { + return { + version: AFFiNE.version, + flavor: SERVER_FLAVOR || 'allinone', + }; + } +} + +@Module({ + providers: [ServerConfigResolver], +}) +export class ServerConfigModule {} diff --git a/packages/backend/server/src/modules/index.ts b/packages/backend/server/src/modules/index.ts index 34458f4a2d..0239a5c5b6 100644 --- a/packages/backend/server/src/modules/index.ts +++ b/packages/backend/server/src/modules/index.ts @@ -3,7 +3,7 @@ import { EventEmitterModule } from '@nestjs/event-emitter'; import { ScheduleModule } from '@nestjs/schedule'; import { GqlModule } from '../graphql.module'; -import { AuthModule } from './auth'; +import { ServerConfigModule } from './config'; import { DocModule } from './doc'; import { PaymentModule } from './payment'; import { SyncModule } from './sync'; @@ -22,13 +22,23 @@ switch (SERVER_FLAVOR) { case 'sync': BusinessModules.push(SyncModule, DocModule.forSync()); break; - case 'graphql': + case 'selfhosted': BusinessModules.push( + ServerConfigModule, + ScheduleModule.forRoot(), + GqlModule, + WorkspaceModule, + UsersModule, + DocModule.forRoot() + ); + break; + case 'graphql': + BusinessModules.push( + ServerConfigModule, ScheduleModule.forRoot(), GqlModule, WorkspaceModule, UsersModule, - AuthModule, DocModule.forRoot(), PaymentModule ); @@ -36,11 +46,11 @@ switch (SERVER_FLAVOR) { case 'allinone': default: BusinessModules.push( + ServerConfigModule, ScheduleModule.forRoot(), GqlModule, WorkspaceModule, UsersModule, - AuthModule, SyncModule, DocModule.forRoot(), PaymentModule @@ -48,4 +58,4 @@ switch (SERVER_FLAVOR) { break; } -export { BusinessModules }; +export { BusinessModules, SERVER_FLAVOR }; diff --git a/packages/backend/server/src/schema.gql b/packages/backend/server/src/schema.gql index 9bbce9fb1c..cd76576875 100644 --- a/packages/backend/server/src/schema.gql +++ b/packages/backend/server/src/schema.gql @@ -2,6 +2,14 @@ # THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY) # ------------------------------------------------------ +type ServerConfigType { + """server version""" + version: String! + + """server flavor""" + flavor: String! +} + type UserType { id: ID! @@ -240,6 +248,9 @@ type DocHistoryType { } type Query { + """server config""" + serverConfig: ServerConfigType! + """Get is owner of workspace""" isOwner(workspaceId: String!): Boolean! diff --git a/packages/frontend/graphql/src/graphql/index.ts b/packages/frontend/graphql/src/graphql/index.ts index 4fd2c04148..86ef26cfd1 100644 --- a/packages/frontend/graphql/src/graphql/index.ts +++ b/packages/frontend/graphql/src/graphql/index.ts @@ -545,6 +545,20 @@ mutation sendVerifyChangeEmail($token: String!, $email: String!, $callbackUrl: S }`, }; +export const serverConfigQuery = { + id: 'serverConfigQuery' as const, + operationName: 'serverConfig', + definitionName: 'serverConfig', + containsFile: false, + query: ` +query serverConfig { + serverConfig { + version + flavor + } +}`, +}; + export const setWorkspacePublicByIdMutation = { id: 'setWorkspacePublicByIdMutation' as const, operationName: 'setWorkspacePublicById', diff --git a/packages/frontend/graphql/src/graphql/server-config.gql b/packages/frontend/graphql/src/graphql/server-config.gql new file mode 100644 index 0000000000..6f7a99a477 --- /dev/null +++ b/packages/frontend/graphql/src/graphql/server-config.gql @@ -0,0 +1,6 @@ +query serverConfig { + serverConfig { + version + flavor + } +} diff --git a/packages/frontend/graphql/src/schema.ts b/packages/frontend/graphql/src/schema.ts index 99b6282ca3..e1d84f572b 100644 --- a/packages/frontend/graphql/src/schema.ts +++ b/packages/frontend/graphql/src/schema.ts @@ -533,6 +533,17 @@ export type SendVerifyChangeEmailMutation = { sendVerifyChangeEmail: boolean; }; +export type ServerConfigQueryVariables = Exact<{ [key: string]: never }>; + +export type ServerConfigQuery = { + __typename?: 'Query'; + serverConfig: { + __typename?: 'ServerConfigType'; + version: string; + flavor: string; + }; +}; + export type SetWorkspacePublicByIdMutationVariables = Exact<{ id: Scalars['ID']['input']; public: Scalars['Boolean']['input']; @@ -732,6 +743,11 @@ export type Queries = variables: PricesQueryVariables; response: PricesQuery; } + | { + name: 'serverConfigQuery'; + variables: ServerConfigQueryVariables; + response: ServerConfigQuery; + } | { name: 'subscriptionQuery'; variables: SubscriptionQueryVariables; From f04ec50d124504d530296a3ab530721dd41a79de Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Sat, 25 Nov 2023 23:15:44 +0800 Subject: [PATCH 02/11] feat: optional payment for frontend (#5056) --- packages/backend/server/src/modules/index.ts | 3 ++ .../server/src/modules/payment/resolver.ts | 2 +- .../server/src/modules/payment/service.ts | 1 + .../backend/server/src/modules/self-hosted.ts | 38 +++++++++++++++++++ packages/backend/server/src/schema.gql | 1 + .../setting-components/storage-progess.tsx | 36 ++++++++++-------- .../affine/auth/user-plan-button.tsx | 5 +++ .../new-workspace-setting-detail/index.tsx | 8 +++- .../new-workspace-setting-detail/members.tsx | 22 +++++++---- .../setting-modal/account-setting/index.tsx | 4 ++ .../setting-modal/general-setting/index.tsx | 27 +++++++------ .../src/hooks/affine/use-server-flavor.ts | 29 ++++++++++++++ .../core/src/hooks/use-subscription.ts | 7 ++++ packages/frontend/graphql/src/schema.ts | 1 + 14 files changed, 146 insertions(+), 38 deletions(-) create mode 100644 packages/backend/server/src/modules/self-hosted.ts create mode 100644 packages/frontend/core/src/hooks/affine/use-server-flavor.ts diff --git a/packages/backend/server/src/modules/index.ts b/packages/backend/server/src/modules/index.ts index 0239a5c5b6..a16215c68e 100644 --- a/packages/backend/server/src/modules/index.ts +++ b/packages/backend/server/src/modules/index.ts @@ -6,6 +6,7 @@ import { GqlModule } from '../graphql.module'; import { ServerConfigModule } from './config'; import { DocModule } from './doc'; import { PaymentModule } from './payment'; +import { SelfHostedModule } from './self-hosted'; import { SyncModule } from './sync'; import { UsersModule } from './users'; import { WorkspaceModule } from './workspaces'; @@ -25,10 +26,12 @@ switch (SERVER_FLAVOR) { case 'selfhosted': BusinessModules.push( ServerConfigModule, + SelfHostedModule, ScheduleModule.forRoot(), GqlModule, WorkspaceModule, UsersModule, + SyncModule, DocModule.forRoot() ); break; diff --git a/packages/backend/server/src/modules/payment/resolver.ts b/packages/backend/server/src/modules/payment/resolver.ts index 913609a76d..7374f8e1d5 100644 --- a/packages/backend/server/src/modules/payment/resolver.ts +++ b/packages/backend/server/src/modules/payment/resolver.ts @@ -52,7 +52,7 @@ class SubscriptionPrice { } @ObjectType('UserSubscription') -class UserSubscriptionType implements Partial { +export class UserSubscriptionType implements Partial { @Field({ name: 'id' }) stripeSubscriptionId!: string; diff --git a/packages/backend/server/src/modules/payment/service.ts b/packages/backend/server/src/modules/payment/service.ts index 6dfbf19218..c30ac03279 100644 --- a/packages/backend/server/src/modules/payment/service.ts +++ b/packages/backend/server/src/modules/payment/service.ts @@ -30,6 +30,7 @@ export enum SubscriptionPlan { Pro = 'pro', Team = 'team', Enterprise = 'enterprise', + SelfHosted = 'selfhosted', } export function encodeLookupKey( diff --git a/packages/backend/server/src/modules/self-hosted.ts b/packages/backend/server/src/modules/self-hosted.ts new file mode 100644 index 0000000000..5bd684b981 --- /dev/null +++ b/packages/backend/server/src/modules/self-hosted.ts @@ -0,0 +1,38 @@ +import { Module } from '@nestjs/common'; +import { ResolveField, Resolver } from '@nestjs/graphql'; + +import { UserSubscriptionType } from './payment/resolver'; +import { + SubscriptionPlan, + SubscriptionRecurring, + SubscriptionStatus, +} from './payment/service'; +import { UserType } from './users'; + +const YEAR = 1000 * 60 * 60 * 24 * 30 * 12; + +@Resolver(() => UserType) +export class SelfHostedDummyResolver { + private readonly start = new Date(); + private readonly end = new Date(Number(this.start) + YEAR); + constructor() {} + + @ResolveField(() => UserSubscriptionType) + async subscription() { + return { + stripeSubscriptionId: 'dummy', + plan: SubscriptionPlan.SelfHosted, + recurring: SubscriptionRecurring.Yearly, + status: SubscriptionStatus.Active, + start: this.start, + end: this.end, + createdAt: this.start, + updatedAt: this.start, + }; + } +} + +@Module({ + providers: [SelfHostedDummyResolver], +}) +export class SelfHostedModule {} diff --git a/packages/backend/server/src/schema.gql b/packages/backend/server/src/schema.gql index cd76576875..68dc28c522 100644 --- a/packages/backend/server/src/schema.gql +++ b/packages/backend/server/src/schema.gql @@ -81,6 +81,7 @@ enum SubscriptionPlan { Pro Team Enterprise + SelfHosted } type UserSubscription { diff --git a/packages/frontend/component/src/components/setting-components/storage-progess.tsx b/packages/frontend/component/src/components/setting-components/storage-progess.tsx index 4532a88ed0..e98c564069 100644 --- a/packages/frontend/component/src/components/setting-components/storage-progess.tsx +++ b/packages/frontend/component/src/components/setting-components/storage-progess.tsx @@ -11,6 +11,7 @@ import * as styles from './share.css'; export interface StorageProgressProgress { max: number; value: number; + upgradable?: boolean; onUpgrade: () => void; plan: SubscriptionPlan; } @@ -23,6 +24,7 @@ enum ButtonType { export const StorageProgress = ({ max: upperLimit, value, + upgradable = true, onUpgrade, plan, }: StorageProgressProgress) => { @@ -63,22 +65,24 @@ export const StorageProgress = ({ - - - - - + {upgradable ? ( + + + + + + ) : null} ); }; diff --git a/packages/frontend/core/src/components/affine/auth/user-plan-button.tsx b/packages/frontend/core/src/components/affine/auth/user-plan-button.tsx index aa0b417c6f..dc1ecfdb29 100644 --- a/packages/frontend/core/src/components/affine/auth/user-plan-button.tsx +++ b/packages/frontend/core/src/components/affine/auth/user-plan-button.tsx @@ -28,6 +28,11 @@ const UserPlanButtonWithData = () => { const t = useAFFiNEI18N(); + if (plan === SubscriptionPlan.SelfHosted) { + // Self hosted version doesn't have a payment apis. + return
{plan}
; + } + return (
diff --git a/packages/frontend/core/src/components/affine/new-workspace-setting-detail/index.tsx b/packages/frontend/core/src/components/affine/new-workspace-setting-detail/index.tsx index 6732ce7b0e..56af1e62ef 100644 --- a/packages/frontend/core/src/components/affine/new-workspace-setting-detail/index.tsx +++ b/packages/frontend/core/src/components/affine/new-workspace-setting-detail/index.tsx @@ -7,6 +7,7 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name'; import { useMemo } from 'react'; +import { useSelfHosted } from '../../../hooks/affine/use-server-flavor'; import { useWorkspace } from '../../../hooks/use-workspace'; import { DeleteLeaveWorkspace } from './delete-leave-workspace'; import { ExportPanel } from './export'; @@ -20,6 +21,7 @@ import type { WorkspaceSettingDetailProps } from './types'; export const WorkspaceSettingDetail = (props: WorkspaceSettingDetailProps) => { const { workspaceId } = props; const t = useAFFiNEI18N(); + const isSelfHosted = useSelfHosted(); const workspace = useWorkspace(workspaceId); const [name] = useBlockSuiteWorkspaceName(workspace.blockSuiteWorkspace); @@ -56,7 +58,11 @@ export const WorkspaceSettingDetail = (props: WorkspaceSettingDetailProps) => { - + {storageAndExportSetting} diff --git a/packages/frontend/core/src/components/affine/new-workspace-setting-detail/members.tsx b/packages/frontend/core/src/components/affine/new-workspace-setting-detail/members.tsx index 687e453467..55926dbb34 100644 --- a/packages/frontend/core/src/components/affine/new-workspace-setting-detail/members.tsx +++ b/packages/frontend/core/src/components/affine/new-workspace-setting-detail/members.tsx @@ -51,6 +51,7 @@ enum MemberLimitCount { const COUNT_PER_PAGE = 8; export interface MembersPanelProps extends WorkspaceSettingDetailProps { + upgradable: boolean; workspace: AffineOfficialWorkspace; } type OnRevoke = (memberId: string) => void; @@ -70,6 +71,7 @@ const MembersPanelLocal = () => { export const CloudWorkspaceMembersPanel = ({ workspace, isOwner, + upgradable, }: MembersPanelProps) => { const workspaceId = workspace.id; const memberCount = useMemberCount(workspaceId); @@ -165,16 +167,20 @@ export const CloudWorkspaceMembersPanel = ({ planName: plan, memberLimit, })} - , -
- - {t['com.affine.payment.member.description.go-upgrade']()} - - -
+ {upgradable ? ( + <> + , +
+ + {t['com.affine.payment.member.description.go-upgrade']()} + + +
+ + ) : null} ); - }, [handleUpgrade, memberLimit, plan, t]); + }, [handleUpgrade, memberLimit, plan, t, upgradable]); return ( <> diff --git a/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx index 2c16543363..4d82b3c5d8 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx @@ -35,6 +35,7 @@ import { openSignOutModalAtom, } from '../../../../atoms'; import { useCurrentUser } from '../../../../hooks/affine/use-current-user'; +import { useSelfHosted } from '../../../../hooks/affine/use-server-flavor'; import { useUserSubscription } from '../../../../hooks/use-subscription'; import { Upload } from '../../../pure/file-upload'; import * as style from './style.css'; @@ -167,6 +168,7 @@ export const AvatarAndName = () => { const StoragePanel = () => { const t = useAFFiNEI18N(); + const isSelfHosted = useSelfHosted(); const { data } = useQuery({ query: allBlobSizesQuery, @@ -175,6 +177,7 @@ const StoragePanel = () => { const [subscription] = useUserSubscription(); const plan = subscription?.plan ?? SubscriptionPlan.Free; + // TODO(@JimmFly): get limit from user usage query directly after #4720 is merged const maxLimit = useMemo(() => { return bytes.parse(plan === SubscriptionPlan.Free ? '10GB' : '100GB'); }, [plan]); @@ -199,6 +202,7 @@ const StoragePanel = () => { plan={plan} value={data.collectAllBlobSizes.size} onUpgrade={onUpgrade} + upgradable={!isSelfHosted} /> ); diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx index 956d99bd5b..2f63a3b1a4 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx @@ -8,6 +8,7 @@ import { import type { ReactElement, SVGProps } from 'react'; import { useCurrentLoginStatus } from '../../../../hooks/affine/use-current-login-status'; +import { useSelfHosted } from '../../../../hooks/affine/use-server-flavor'; import { AboutAffine } from './about'; import { AppearanceSettings } from './appearance'; import { BillingSettings } from './billing'; @@ -36,6 +37,7 @@ export type GeneralSettingList = GeneralSettingListItem[]; export const useGeneralSettingList = (): GeneralSettingList => { const t = useAFFiNEI18N(); const status = useCurrentLoginStatus(); + const isSelfHosted = useSelfHosted(); const settings: GeneralSettingListItem[] = [ { @@ -50,13 +52,6 @@ export const useGeneralSettingList = (): GeneralSettingList => { icon: KeyboardIcon, testId: 'shortcuts-panel-trigger', }, - { - key: 'plans', - title: t['com.affine.payment.title'](), - icon: UpgradeIcon, - testId: 'plans-panel-trigger', - }, - { key: 'plugins', title: 'Plugins', @@ -71,13 +66,21 @@ export const useGeneralSettingList = (): GeneralSettingList => { }, ]; - if (status === 'authenticated') { + if (!isSelfHosted) { settings.splice(3, 0, { - key: 'billing', - title: t['com.affine.payment.billing-setting.title'](), - icon: PaymentIcon, - testId: 'billing-panel-trigger', + key: 'plans', + title: t['com.affine.payment.title'](), + icon: UpgradeIcon, + testId: 'plans-panel-trigger', }); + if (status === 'authenticated') { + settings.splice(3, 0, { + key: 'billing', + title: t['com.affine.payment.billing-setting.title'](), + icon: PaymentIcon, + testId: 'billing-panel-trigger', + }); + } } return settings; diff --git a/packages/frontend/core/src/hooks/affine/use-server-flavor.ts b/packages/frontend/core/src/hooks/affine/use-server-flavor.ts new file mode 100644 index 0000000000..6ffb71257c --- /dev/null +++ b/packages/frontend/core/src/hooks/affine/use-server-flavor.ts @@ -0,0 +1,29 @@ +import { serverConfigQuery } from '@affine/graphql'; +import { useQuery } from '@affine/workspace/affine/gql'; +import type { BareFetcher, Middleware } from 'swr'; + +const wrappedFetcher = (fetcher: BareFetcher | null, ...args: any[]) => + fetcher?.(...args).catch(() => null); + +const errorHandler: Middleware = useSWRNext => (key, fetcher, config) => { + return useSWRNext(key, wrappedFetcher.bind(null, fetcher), config); +}; + +export const useServerFlavor = () => { + const { data: config, error } = useQuery( + { query: serverConfigQuery }, + { use: [errorHandler] } + ); + + if (error || !config) { + return 'local'; + } + + return config.serverConfig.flavor; +}; + +export const useSelfHosted = () => { + const serverFlavor = useServerFlavor(); + + return ['local', 'selfhosted'].includes(serverFlavor); +}; diff --git a/packages/frontend/core/src/hooks/use-subscription.ts b/packages/frontend/core/src/hooks/use-subscription.ts index bdc254c71d..9ec556cb79 100644 --- a/packages/frontend/core/src/hooks/use-subscription.ts +++ b/packages/frontend/core/src/hooks/use-subscription.ts @@ -2,6 +2,8 @@ import { type SubscriptionQuery, subscriptionQuery } from '@affine/graphql'; import { useQuery } from '@affine/workspace/affine/gql'; import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks'; +import { useSelfHosted } from './affine/use-server-flavor'; + export type Subscription = NonNullable< NonNullable['subscription'] >; @@ -12,6 +14,7 @@ const selector = (data: SubscriptionQuery) => data.currentUser?.subscription ?? null; export const useUserSubscription = () => { + const isSelfHosted = useSelfHosted(); const { data, mutate } = useQuery({ query: subscriptionQuery, }); @@ -36,5 +39,9 @@ export const useUserSubscription = () => { [mutate] ); + if (isSelfHosted) { + return [selector(data), () => {}] as const; + } + return [selector(data), set] as const; }; diff --git a/packages/frontend/graphql/src/schema.ts b/packages/frontend/graphql/src/schema.ts index e1d84f572b..61b4b4020c 100644 --- a/packages/frontend/graphql/src/schema.ts +++ b/packages/frontend/graphql/src/schema.ts @@ -62,6 +62,7 @@ export enum SubscriptionPlan { Enterprise = 'Enterprise', Free = 'Free', Pro = 'Pro', + SelfHosted = 'SelfHosted', Team = 'Team', } From 34d575078c1edb9debefa904ba69ea8812dd1c6b Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Mon, 27 Nov 2023 02:41:19 +0000 Subject: [PATCH 03/11] feat(core): simple recovery history ui poc (#5033) Simple recovery history UI poc. What's missing - [x] e2e All biz logic should be done, excluding complete ui details. - [ ] offline prompt - [ ] history timeline - [ ] page ui https://github.com/toeverything/AFFiNE/assets/584378/fc3f6a48-ff7f-4265-b9f5-9c0087cb2635 --- .../backend/server/src/modules/doc/history.ts | 2 +- packages/common/env/src/global.ts | 1 + .../frontend/core/.webpack/runtime-config.ts | 8 + .../frontend/core/src/atoms/page-history.ts | 7 + .../affine/page-history-modal/data.ts | 251 ++++++++++ .../empty-history-shape.tsx | 119 +++++ .../page-history-modal/history-modal.tsx | 446 ++++++++++++++++++ .../affine/page-history-modal/index.tsx | 1 + .../affine/page-history-modal/styles.css.ts | 185 ++++++++ .../operation-menu.tsx | 36 +- .../src/components/root-app-sidebar/index.tsx | 4 +- .../core/src/hooks/affine/use-mutate-cloud.ts | 1 + ...se-register-blocksuite-editor-commands.tsx | 40 +- .../src/hooks/affine/use-server-flavor.ts | 7 +- ...nds.ts => use-browser-history-commands.ts} | 2 +- .../core/src/pages/workspace/detail-page.tsx | 5 +- .../graphql/src/graphql/histories.gql | 13 + .../frontend/graphql/src/graphql/index.ts | 27 ++ .../graphql/src/graphql/recover-doc.gql | 7 + packages/frontend/graphql/src/schema.ts | 40 ++ packages/frontend/i18n/src/resources/en.json | 11 +- packages/frontend/workspace/package.json | 1 + packages/frontend/workspace/src/affine/gql.ts | 91 +++- 23 files changed, 1291 insertions(+), 14 deletions(-) create mode 100644 packages/frontend/core/src/atoms/page-history.ts create mode 100644 packages/frontend/core/src/components/affine/page-history-modal/data.ts create mode 100644 packages/frontend/core/src/components/affine/page-history-modal/empty-history-shape.tsx create mode 100644 packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx create mode 100644 packages/frontend/core/src/components/affine/page-history-modal/index.tsx create mode 100644 packages/frontend/core/src/components/affine/page-history-modal/styles.css.ts rename packages/frontend/core/src/hooks/{use-shortcut-commands.ts => use-browser-history-commands.ts} (95%) create mode 100644 packages/frontend/graphql/src/graphql/histories.gql create mode 100644 packages/frontend/graphql/src/graphql/recover-doc.gql diff --git a/packages/backend/server/src/modules/doc/history.ts b/packages/backend/server/src/modules/doc/history.ts index ddb869d18e..2a6dc47554 100644 --- a/packages/backend/server/src/modules/doc/history.ts +++ b/packages/backend/server/src/modules/doc/history.ts @@ -89,7 +89,7 @@ export class DocHistoryManager { workspaceId, id, timestamp: { - lte: before, + lt: before, }, // only include the ones has not expired expiredAt: { diff --git a/packages/common/env/src/global.ts b/packages/common/env/src/global.ts index 5699cc6e19..7e2125a38e 100644 --- a/packages/common/env/src/global.ts +++ b/packages/common/env/src/global.ts @@ -32,6 +32,7 @@ export const runtimeFlagsSchema = z.object({ enableCaptcha: z.boolean(), enableEnhanceShareMode: z.boolean(), enablePayment: z.boolean(), + enablePageHistory: z.boolean(), // this is for the electron app serverUrlPrefix: z.string(), enableMoveDatabase: z.boolean(), diff --git a/packages/frontend/core/.webpack/runtime-config.ts b/packages/frontend/core/.webpack/runtime-config.ts index 52eead3d66..e54ac2410d 100644 --- a/packages/frontend/core/.webpack/runtime-config.ts +++ b/packages/frontend/core/.webpack/runtime-config.ts @@ -33,6 +33,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { enableCaptcha: true, enableEnhanceShareMode: false, enablePayment: true, + enablePageHistory: false, serverUrlPrefix: 'https://insider.affine.pro', // Let insider be stable environment temporarily. editorFlags, appVersion: packageJson.version, @@ -41,6 +42,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { get beta() { return { ...this.stable, + enablePageHistory: false, serverUrlPrefix: 'https://insider.affine.pro', }; }, @@ -75,6 +77,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { enableCaptcha: true, enableEnhanceShareMode: false, enablePayment: true, + enablePageHistory: true, serverUrlPrefix: 'https://affine.fail', editorFlags, appVersion: packageJson.version, @@ -142,6 +145,11 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { : buildFlags.mode === 'development' ? true : currentBuildPreset.enablePayment, + enablePageHistory: process.env.ENABLE_PAGE_HISTORY + ? process.env.ENABLE_PAGE_HISTORY === 'true' + : buildFlags.mode === 'development' + ? true + : currentBuildPreset.enablePageHistory, }; if (buildFlags.mode === 'development') { diff --git a/packages/frontend/core/src/atoms/page-history.ts b/packages/frontend/core/src/atoms/page-history.ts new file mode 100644 index 0000000000..aef79debb7 --- /dev/null +++ b/packages/frontend/core/src/atoms/page-history.ts @@ -0,0 +1,7 @@ +import { atom } from 'jotai'; + +// make page history controllable by atom to make it easier to use in CMDK +export const pageHistoryModalAtom = atom({ + open: false, + pageId: '', +}); diff --git a/packages/frontend/core/src/components/affine/page-history-modal/data.ts b/packages/frontend/core/src/components/affine/page-history-modal/data.ts new file mode 100644 index 0000000000..c3844ebd7c --- /dev/null +++ b/packages/frontend/core/src/components/affine/page-history-modal/data.ts @@ -0,0 +1,251 @@ +import { DebugLogger } from '@affine/debug'; +import { + fetchWithTraceReport, + type ListHistoryQuery, + listHistoryQuery, + recoverDocMutation, +} from '@affine/graphql'; +import { + useMutateQueryResource, + useMutation, + useQueryInfinite, +} from '@affine/workspace/affine/gql'; +import { createAffineCloudBlobEngine } from '@affine/workspace/blob'; +import { globalBlockSuiteSchema } from '@affine/workspace/manager'; +import { assertEquals } from '@blocksuite/global/utils'; +import { Workspace } from '@blocksuite/store'; +import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta'; +import { useBlockSuiteWorkspacePage } from '@toeverything/hooks/use-block-suite-workspace-page'; +import { revertUpdate } from '@toeverything/y-indexeddb'; +import { useMemo } from 'react'; +import useSWRImmutable from 'swr/immutable'; +import { applyUpdate } from 'yjs'; + +const logger = new DebugLogger('page-history'); + +type DocHistory = ListHistoryQuery['workspace']['histories'][number]; + +export const usePageSnapshotList = (workspaceId: string, pageDocId: string) => { + const pageSize = 10; + const { data, loadingMore, loadMore } = useQueryInfinite({ + query: listHistoryQuery, + getVariables: (_, previousPageData) => { + // use the timestamp of the last history as the cursor + const before = previousPageData?.workspace.histories.at(-1)?.timestamp; + const vars = { + pageDocId: pageDocId, + workspaceId: workspaceId, + before: before, + take: pageSize, + }; + + return vars; + }, + }); + + const shouldLoadMore = useMemo(() => { + if (!data) { + return false; + } + const lastPage = data.at(-1); + if (!lastPage) { + return false; + } + return lastPage.workspace.histories.length === pageSize; + }, [data]); + + const histories = useMemo(() => { + if (!data) { + return []; + } + return data.flatMap(page => page.workspace.histories); + }, [data]); + + return [ + histories, + shouldLoadMore ? loadMore : undefined, + loadingMore, + ] as const; +}; + +const snapshotFetcher = async ( + [workspaceId, pageDocId, ts]: [ + workspaceId: string, + pageDocId: string, + ts: string, + ] // timestamp is the key to the history/snapshot +) => { + if (!ts) { + return null; + } + const res = await fetchWithTraceReport( + runtimeConfig.serverUrlPrefix + + `/api/workspaces/${workspaceId}/docs/${pageDocId}/histories/${ts}`, + { + priority: 'high', + } + ); + + if (!res.ok) { + throw new Error('Failed to fetch snapshot'); + } + + const snapshot = await res.arrayBuffer(); + if (!snapshot) { + throw new Error('Invalid snapshot'); + } + return snapshot; +}; + +// attach the Page shown in the modal to a temporary workspace +// so that we do not need to worry about providers etc +// todo: fix references to the page (the referenced page will shown as deleted) +// if we simply clone the current workspace, it maybe time consuming right? +const workspaceMap = new Map(); + +// assume the workspace is a cloud workspace since the history feature is only enabled for cloud workspace +const getOrCreateWorkspace = (workspaceId: string) => { + let workspace = workspaceMap.get(workspaceId); + if (!workspace) { + const blobEngine = createAffineCloudBlobEngine(workspaceId); + workspace = new Workspace({ + id: workspaceId, + providerCreators: [], + blobStorages: [ + () => ({ + crud: { + async get(key) { + return (await blobEngine.get(key)) ?? null; + }, + async set(key, value) { + await blobEngine.set(key, value); + return key; + }, + async delete(key) { + return blobEngine.delete(key); + }, + async list() { + return blobEngine.list(); + }, + }, + }), + ], + schema: globalBlockSuiteSchema, + }); + workspaceMap.set(workspaceId, workspace); + } + return workspace; +}; + +// workspace id + page id + timestamp -> snapshot (update binary) +export const usePageHistory = ( + workspaceId: string, + pageDocId: string, + ts?: string +) => { + // snapshot should be immutable. so we use swr immutable to disable revalidation + const { data } = useSWRImmutable( + [workspaceId, pageDocId, ts], + { + fetcher: snapshotFetcher, + suspense: false, + } + ); + return data ?? undefined; +}; + +// workspace id + page id + timestamp + snapshot -> Page (to be used for rendering in blocksuite editor) +export const useSnapshotPage = ( + workspaceId: string, + pageDocId: string, + ts?: string, + snapshot?: ArrayBuffer +) => { + const page = useMemo(() => { + if (!ts) { + return null; + } + const pageId = pageDocId + '-' + ts; + const historyShellWorkspace = getOrCreateWorkspace(workspaceId); + let page = historyShellWorkspace.getPage(pageId); + if (!page && snapshot) { + page = historyShellWorkspace.createPage({ + id: pageId, + }); + page.awarenessStore.setReadonly(page, true); + const spaceDoc = page.spaceDoc; + page + .load(() => applyUpdate(spaceDoc, new Uint8Array(snapshot))) + .catch(console.error); // must load before applyUpdate + } + return page; + }, [pageDocId, snapshot, ts, workspaceId]); + + return page; +}; + +export const historyListGroupByDay = (histories: DocHistory[]) => { + const map = new Map(); + for (const history of histories) { + const day = new Date(history.timestamp).toLocaleDateString(); + const list = map.get(day) ?? []; + list.push(history); + map.set(day, list); + } + return [...map.entries()]; +}; + +export const useRestorePage = (workspace: Workspace, pageId: string) => { + const page = useBlockSuiteWorkspacePage(workspace, pageId); + const mutateQueryResource = useMutateQueryResource(); + const { trigger: recover, isMutating } = useMutation({ + mutation: recoverDocMutation, + }); + const { getPageMeta, setPageTitle } = usePageMetaHelper(workspace); + + const onRestore = useMemo(() => { + return async (version: string, update: Uint8Array) => { + if (!page) { + return; + } + const pageDocId = page.spaceDoc.guid; + revertUpdate(page.spaceDoc, update, key => { + assertEquals(key, 'blocks'); // only expect this value is 'blocks' + return 'Map'; + }); + + // should also update the page title, since it may be changed in the history + const title = page.meta.title; + + if (getPageMeta(pageDocId)?.title !== title) { + setPageTitle(pageDocId, title); + } + + await recover({ + docId: pageDocId, + timestamp: version, + workspaceId: workspace.id, + }); + + await mutateQueryResource(listHistoryQuery, vars => { + return ( + vars.pageDocId === pageDocId && vars.workspaceId === workspace.id + ); + }); + + logger.info('Page restored', pageDocId, version); + }; + }, [ + getPageMeta, + mutateQueryResource, + page, + recover, + setPageTitle, + workspace.id, + ]); + + return { + onRestore, + isMutating, + }; +}; diff --git a/packages/frontend/core/src/components/affine/page-history-modal/empty-history-shape.tsx b/packages/frontend/core/src/components/affine/page-history-modal/empty-history-shape.tsx new file mode 100644 index 0000000000..d36d99de89 --- /dev/null +++ b/packages/frontend/core/src/components/affine/page-history-modal/empty-history-shape.tsx @@ -0,0 +1,119 @@ +export const EmptyHistoryShape = () => ( + + + + + + + + + + + + + + + + + + + + + +); diff --git a/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx b/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx new file mode 100644 index 0000000000..220fe3ef2f --- /dev/null +++ b/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx @@ -0,0 +1,446 @@ +import { Scrollable } from '@affine/component'; +import { + BlockSuiteEditor, + BlockSuiteFallback, +} from '@affine/component/block-suite-editor'; +import type { PageMode } from '@affine/core/atoms'; +import { useAFFiNEI18N } from '@affine/i18n/hooks'; +import type { Workspace } from '@blocksuite/store'; +import type { DialogContentProps } from '@radix-ui/react-dialog'; +import { Button } from '@toeverything/components/button'; +import { ConfirmModal, Modal } from '@toeverything/components/modal'; +import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks'; +import { useAtom, useAtomValue } from 'jotai'; +import { + type PropsWithChildren, + Suspense, + useCallback, + useLayoutEffect, + useMemo, + useState, +} from 'react'; + +import { currentModeAtom } from '../../../atoms/mode'; +import { pageHistoryModalAtom } from '../../../atoms/page-history'; +import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; +import { StyledEditorModeSwitch } from '../../blocksuite/block-suite-mode-switch/style'; +import { + EdgelessSwitchItem, + PageSwitchItem, +} from '../../blocksuite/block-suite-mode-switch/switch-items'; +import { AffineErrorBoundary } from '../affine-error-boundary'; +import { + historyListGroupByDay, + usePageHistory, + usePageSnapshotList, + useRestorePage, + useSnapshotPage, +} from './data'; +import { EmptyHistoryShape } from './empty-history-shape'; +import * as styles from './styles.css'; + +export interface PageHistoryModalProps { + open: boolean; + onOpenChange: (open: boolean) => void; + workspace: Workspace; + pageId: string; +} + +const contentOptions: DialogContentProps = { + ['data-testid' as string]: 'page-history-modal', + onPointerDownOutside: e => { + e.preventDefault(); + }, + style: { + padding: 0, + maxWidth: 944, + backgroundColor: 'var(--affine-background-primary-color)', + overflow: 'hidden', + }, +}; + +const ModalContainer = ({ + onOpenChange, + open, + children, +}: PropsWithChildren<{ + open: boolean; + onOpenChange: (open: boolean) => void; +}>) => { + return ( + + {children} + + ); +}; + +const localTimeFormatter = new Intl.DateTimeFormat('en', { + timeStyle: 'short', +}); + +const timestampToLocalTime = (ts: string) => { + return localTimeFormatter.format(new Date(ts)); +}; + +interface HistoryEditorPreviewProps { + workspaceId: string; + pageDocId: string; + ts?: string; + snapshot?: ArrayBuffer; + mode: PageMode; + onModeChange: (mode: PageMode) => void; + title: string; +} + +const HistoryEditorPreview = ({ + ts, + snapshot, + onModeChange, + mode, + workspaceId, + pageDocId, + title, +}: HistoryEditorPreviewProps) => { + const onSwitchToPageMode = useCallback(() => { + onModeChange('page'); + }, [onModeChange]); + const onSwitchToEdgelessMode = useCallback(() => { + onModeChange('edgeless'); + }, [onModeChange]); + const page = useSnapshotPage(workspaceId, pageDocId, ts, snapshot); + + return ( +
+
+ + + + + +
{title}
+ +
+ {ts ? timestampToLocalTime(ts) : null} +
+
+ + {page ? ( + + ) : ( + + )} +
+ ); +}; + +const PageHistoryList = ({ + pageDocId, + workspaceId, + activeVersion, + onVersionChange, +}: { + workspaceId: string; + pageDocId: string; + activeVersion?: string; + onVersionChange: (version: string) => void; +}) => { + const [historyList, loadMore, loadingMore] = usePageSnapshotList( + workspaceId, + pageDocId + ); + const historyListByDay = useMemo(() => { + return historyListGroupByDay(historyList); + }, [historyList]); + + const t = useAFFiNEI18N(); + + useLayoutEffect(() => { + if (historyList.length > 0 && !activeVersion) { + onVersionChange(historyList[0].timestamp); + } + }, [activeVersion, historyList, onVersionChange]); + + return ( +
+
+ {t['com.affine.history.version-history']()} +
+ + + {historyListByDay.map(([day, list]) => { + return ( +
+
{day}
+ {list.map(history => ( +
{ + e.stopPropagation(); + onVersionChange(history.timestamp); + }} + data-active={activeVersion === history.timestamp} + > + +
+ ))} +
+ ); + })} + {loadMore ? ( + + ) : null} +
+ +
+
+ ); +}; + +interface ConfirmRestoreModalProps { + open: boolean; + onConfirm: (res: boolean) => void; + isMutating: boolean; +} + +const ConfirmRestoreModal = ({ + isMutating, + open, + onConfirm, +}: ConfirmRestoreModalProps) => { + const t = useAFFiNEI18N(); + + const handleConfirm = useCallback(() => { + onConfirm(true); + }, [onConfirm]); + + const handleCancel = useCallback(() => { + onConfirm(false); + }, [onConfirm]); + + return ( + + ); +}; + +const EmptyHistoryPrompt = () => { + const t = useAFFiNEI18N(); + + return ( +
+ +
+ {t['com.affine.history.empty-prompt.title']()} +
+
+ {t['com.affine.history.empty-prompt.description']()} +
+
+ ); +}; + +const PageHistoryManager = ({ + workspace, + pageId, + onClose, +}: { + workspace: Workspace; + pageId: string; + onClose: () => void; +}) => { + const workspaceId = workspace.id; + const [activeVersion, setActiveVersion] = useState(); + + const pageDocId = useMemo(() => { + return workspace.getPage(pageId)?.spaceDoc.guid ?? pageId; + }, [pageId, workspace]); + + const snapshot = usePageHistory(workspaceId, pageDocId, activeVersion); + + const t = useAFFiNEI18N(); + + const { onRestore, isMutating } = useRestorePage(workspace, pageId); + + const handleRestore = useMemo( + () => async () => { + if (!activeVersion || !snapshot) { + return; + } + await onRestore(activeVersion, new Uint8Array(snapshot)); + // close the modal after restore + onClose(); + }, + [activeVersion, onClose, onRestore, snapshot] + ); + + const defaultPreviewPageMode = useAtomValue(currentModeAtom); + const [mode, setMode] = useState(defaultPreviewPageMode); + + const title = useMemo( + () => workspace.getPage(pageId)?.meta.title || t['Untitled'](), + [pageId, t, workspace] + ); + + const [showRestoreConfirmModal, setShowRestoreConfirmModal] = useState(false); + + const showRestoreConfirm = useCallback(() => { + setShowRestoreConfirmModal(true); + }, []); + + const onConfirmRestore = useAsyncCallback( + async res => { + if (res) { + await handleRestore(); + } + setShowRestoreConfirmModal(false); + }, + [handleRestore] + ); + + return ( +
+
+ + + +
+ + {!activeVersion ? ( +
+ +
+ ) : null} + +
+ +
+ +
+ + +
+ ); +}; + +export const PageHistoryModal = ({ + onOpenChange, + open, + pageId, + workspace, +}: PageHistoryModalProps) => { + const onClose = useCallback(() => { + onOpenChange(false); + }, [onOpenChange]); + + return ( + + }> + + + + ); +}; + +export const GlobalPageHistoryModal = () => { + const [{ open, pageId }, setState] = useAtom(pageHistoryModalAtom); + const [workspace] = useCurrentWorkspace(); + + const handleOpenChange = useCallback( + (open: boolean) => { + setState(prev => ({ + ...prev, + open, + })); + }, + [setState] + ); + + return ( + + ); +}; diff --git a/packages/frontend/core/src/components/affine/page-history-modal/index.tsx b/packages/frontend/core/src/components/affine/page-history-modal/index.tsx new file mode 100644 index 0000000000..3df0bbb51e --- /dev/null +++ b/packages/frontend/core/src/components/affine/page-history-modal/index.tsx @@ -0,0 +1 @@ +export * from './history-modal'; diff --git a/packages/frontend/core/src/components/affine/page-history-modal/styles.css.ts b/packages/frontend/core/src/components/affine/page-history-modal/styles.css.ts new file mode 100644 index 0000000000..8694b73337 --- /dev/null +++ b/packages/frontend/core/src/components/affine/page-history-modal/styles.css.ts @@ -0,0 +1,185 @@ +import { createVar, globalStyle, style } from '@vanilla-extract/css'; + +const headerHeight = createVar('header-height'); +const footerHeight = createVar('footer-height'); +const historyListWidth = createVar('history-list-width'); + +export const root = style({ + height: '100%', + width: '100%', + vars: { + [headerHeight]: '52px', + [footerHeight]: '68px', + [historyListWidth]: '160px', + }, +}); + +export const modalContent = style({ + display: 'flex', + height: `calc(100% - ${footerHeight})`, + width: '100%', + position: 'absolute', + selectors: { + '&[data-empty="true"]': { + opacity: 0, + pointerEvents: 'none', + }, + }, +}); + +export const previewWrapper = style({ + display: 'flex', + flexDirection: 'column', + flexGrow: 1, + height: '100%', + width: `calc(100% - ${historyListWidth})`, + backgroundColor: 'var(--affine-background-secondary-color)', +}); + +export const previewHeader = style({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + height: headerHeight, + borderBottom: '1px solid var(--affine-border-color)', + backgroundColor: 'var(--affine-background-primary-color)', + padding: '0 12px', + flexShrink: 0, + gap: 12, +}); + +export const previewHeaderTitle = style({ + fontSize: 'var(--affine-font-xs)', + fontWeight: 600, + maxWidth: 400, // better responsiveness +}); + +export const previewHeaderTimestamp = style({ + color: 'var(--affine-text-secondary-color)', + backgroundColor: 'var(--affine-background-secondary-color)', + padding: '0 10px', + borderRadius: 4, + fontSize: 'var(--affine-font-xs)', +}); + +export const editor = style({ + height: '100%', + flexGrow: 1, + overflow: 'hidden', +}); + +export const historyList = style({ + overflow: 'hidden', + height: '100%', + width: historyListWidth, + flexShrink: 0, + borderLeft: '1px solid var(--affine-border-color)', +}); + +export const historyListScrollable = style({ + height: `calc(100% - ${headerHeight})`, +}); + +export const historyListScrollableInner = style({ + display: 'flex', + gap: 16, + flexDirection: 'column', +}); + +export const historyListHeader = style({ + display: 'flex', + alignItems: 'center', + height: 52, + borderBottom: '1px solid var(--affine-border-color)', + fontWeight: 'bold', + flexShrink: 0, + padding: '0 12px', +}); + +export const historyItemGroup = style({ + display: 'flex', + flexDirection: 'column', + rowGap: 6, +}); + +export const historyItemGroupTitle = style({ + display: 'flex', + alignItems: 'center', + padding: '12px', + fontWeight: 'bold', + backgroundColor: 'var(--affine-background-primary-color)', + position: 'sticky', + top: 0, +}); + +export const historyItem = style({ + display: 'flex', + alignItems: 'center', + padding: '0 12px', + height: 32, + cursor: 'pointer', + selectors: { + '&:hover, &[data-active=true]': { + backgroundColor: 'var(--affine-hover-color)', + }, + }, +}); + +export const historyItemLoadMore = style([ + historyItem, + { + cursor: 'pointer', + color: 'var(--affine-text-secondary-color)', + flexShrink: 0, + borderRadius: 0, + selectors: { + '&:hover': { + backgroundColor: 'var(--affine-hover-color)', + }, + }, + }, +]); + +globalStyle(`${historyItem} button`, { + color: 'inherit', +}); + +export const historyFooter = style({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + height: 68, + borderTop: '1px solid var(--affine-border-color)', + padding: '0 24px', + position: 'absolute', + bottom: 0, + left: 0, + right: 0, +}); + +export const spacer = style({ + flexGrow: 1, +}); + +export const emptyHistoryPrompt = style({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + height: '100%', + width: '100%', + zIndex: 1, + gap: 20, +}); + +export const emptyHistoryPromptTitle = style({ + fontWeight: 600, + fontSize: 'var(--affine-font-h-5)', +}); + +export const emptyHistoryPromptDescription = style({ + width: 320, + textAlign: 'center', + fontSize: 'var(--affine-font-xs)', + color: 'var(--affine-text-secondary-color)', +}); diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-header-title/operation-menu.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-header-title/operation-menu.tsx index 42c702a40c..5d19c820da 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-header-title/operation-menu.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-header-title/operation-menu.tsx @@ -1,5 +1,6 @@ import { FlexWrapper } from '@affine/component'; import { Export, MoveToTrash } from '@affine/component/page-list'; +import { WorkspaceFlavour } from '@affine/env/workspace'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { assertExists } from '@blocksuite/global/utils'; import { @@ -8,6 +9,7 @@ import { EditIcon, FavoritedIcon, FavoriteIcon, + HistoryIcon, ImportIcon, PageIcon, } from '@blocksuite/icons'; @@ -25,7 +27,7 @@ import { } from '@toeverything/hooks/use-block-suite-page-meta'; import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper'; import { useAtomValue, useSetAtom } from 'jotai'; -import { useCallback, useRef } from 'react'; +import { useCallback, useRef, useState } from 'react'; import { applyUpdate, encodeStateAsUpdate } from 'yjs'; import { setPageModeAtom } from '../../../atoms'; @@ -36,6 +38,7 @@ import { useTrashModalHelper } from '../../../hooks/affine/use-trash-modal-helpe import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; import { useNavigateHelper } from '../../../hooks/use-navigate-helper'; import { toast } from '../../../utils'; +import { PageHistoryModal } from '../../affine/page-history-modal/history-modal'; import { HeaderDropDownButton } from '../../pure/header-drop-down-button'; import { usePageHelper } from '../block-suite-page-list/utils'; @@ -68,6 +71,12 @@ export const PageMenu = ({ rename, pageId }: PageMenuProps) => { const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace); const { setTrashModal } = useTrashModalHelper(blockSuiteWorkspace); + const [historyModalOpen, setHistoryModalOpen] = useState(false); + + const openHistoryModal = useCallback(() => { + setHistoryModalOpen(true); + }, []); + const handleOpenTrashModal = useCallback(() => { setTrashModal({ open: true, @@ -207,6 +216,23 @@ export const PageMenu = ({ rename, pageId }: PageMenuProps) => { > {t['Import']()} + + {workspace.flavour === WorkspaceFlavour.AFFINE_CLOUD && + runtimeConfig.enablePageHistory ? ( + + + + } + data-testid="editor-option-menu-history" + onSelect={openHistoryModal} + style={menuItemStyle} + > + {t['com.affine.history.view-history-version']()} + + ) : null} + { > + {workspace.flavour === WorkspaceFlavour.AFFINE_CLOUD ? ( + + ) : null} ); }; diff --git a/packages/frontend/core/src/components/root-app-sidebar/index.tsx b/packages/frontend/core/src/components/root-app-sidebar/index.tsx index c5367a1530..3b82e54e26 100644 --- a/packages/frontend/core/src/components/root-app-sidebar/index.tsx +++ b/packages/frontend/core/src/components/root-app-sidebar/index.tsx @@ -30,8 +30,8 @@ import { useAppSettingHelper } from '../../hooks/affine/use-app-setting-helper'; import { useDeleteCollectionInfo } from '../../hooks/affine/use-delete-collection-info'; import { useGeneralShortcuts } from '../../hooks/affine/use-shortcuts'; import { useTrashModalHelper } from '../../hooks/affine/use-trash-modal-helper'; +import { useRegisterBrowserHistoryCommands } from '../../hooks/use-browser-history-commands'; import { useNavigateHelper } from '../../hooks/use-navigate-helper'; -import { useRegisterBlocksuiteEditorCommands } from '../../hooks/use-shortcut-commands'; import type { AllWorkspace } from '../../shared'; import { CollectionsList } from '../pure/workspace-slider-bar/collections'; import { AddCollectionButton } from '../pure/workspace-slider-bar/collections/add-collection-button'; @@ -169,7 +169,7 @@ export const RootAppSidebar = ({ const closeUserWorkspaceList = useCallback(() => { setOpenUserWorkspaceList(false); }, [setOpenUserWorkspaceList]); - useRegisterBlocksuiteEditorCommands(router.back, router.forward); + useRegisterBrowserHistoryCommands(router.back, router.forward); const userInfo = useDeleteCollectionInfo(); return ( { + // todo: should not mutate all graphql cache return mutate(key => { if (Array.isArray(key)) { return key[0] === 'cloud'; diff --git a/packages/frontend/core/src/hooks/affine/use-register-blocksuite-editor-commands.tsx b/packages/frontend/core/src/hooks/affine/use-register-blocksuite-editor-commands.tsx index d7f6cd5134..62ddb8b48b 100644 --- a/packages/frontend/core/src/hooks/affine/use-register-blocksuite-editor-commands.tsx +++ b/packages/frontend/core/src/hooks/affine/use-register-blocksuite-editor-commands.tsx @@ -1,25 +1,29 @@ import { toast } from '@affine/component'; +import { WorkspaceFlavour } from '@affine/env/workspace'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { assertExists } from '@blocksuite/global/utils'; -import { EdgelessIcon, PageIcon } from '@blocksuite/icons'; -import type { Workspace } from '@blocksuite/store'; +import { EdgelessIcon, HistoryIcon, PageIcon } from '@blocksuite/icons'; import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta'; import { PreconditionStrategy, registerAffineCommand, } from '@toeverything/infra/command'; +import { useSetAtom } from 'jotai'; import { useCallback, useEffect } from 'react'; +import { pageHistoryModalAtom } from '../../atoms/page-history'; +import { useCurrentWorkspace } from '../current/use-current-workspace'; import { useBlockSuiteMetaHelper } from './use-block-suite-meta-helper'; import { useExportPage } from './use-export-page'; import { useTrashModalHelper } from './use-trash-modal-helper'; export function useRegisterBlocksuiteEditorCommands( - blockSuiteWorkspace: Workspace, pageId: string, mode: 'page' | 'edgeless' ) { const t = useAFFiNEI18N(); + const [workspace] = useCurrentWorkspace(); + const blockSuiteWorkspace = workspace.blockSuiteWorkspace; const { getPageMeta } = usePageMetaHelper(blockSuiteWorkspace); const currentPage = blockSuiteWorkspace.getPage(pageId); assertExists(currentPage); @@ -28,6 +32,15 @@ export function useRegisterBlocksuiteEditorCommands( const favorite = pageMeta.favorite ?? false; const trash = pageMeta.trash ?? false; + const setPageHistoryModalState = useSetAtom(pageHistoryModalAtom); + + const openHistoryModal = useCallback(() => { + setPageHistoryModalState(() => ({ + pageId, + open: true, + })); + }, [pageId, setPageHistoryModalState]); + const { togglePageMode, toggleFavorite, restoreFromTrash } = useBlockSuiteMetaHelper(blockSuiteWorkspace); const exportHandler = useExportPage(currentPage); @@ -40,12 +53,14 @@ export function useRegisterBlocksuiteEditorCommands( }); }, [pageId, pageMeta.title, setTrashModal]); + const isCloudWorkspace = workspace.flavour === WorkspaceFlavour.AFFINE_CLOUD; + useEffect(() => { const unsubs: Array<() => void> = []; const preconditionStrategy = () => PreconditionStrategy.InPaperOrEdgeless && !trash; - //TODO: add back when edgeless presentation is ready + // TODO: add back when edgeless presentation is ready // this is pretty hack and easy to break. need a better way to communicate with blocksuite editor // unsubs.push( @@ -189,6 +204,20 @@ export function useRegisterBlocksuiteEditorCommands( }) ); + if (runtimeConfig.enablePageHistory && isCloudWorkspace) { + unsubs.push( + registerAffineCommand({ + id: `editor:${mode}-page-history`, + category: `editor:${mode}`, + icon: , + label: t['com.affine.cmdk.affine.editor.reveal-page-history-modal'](), + run() { + openHistoryModal(); + }, + }) + ); + } + return () => { unsubs.forEach(unsub => unsub()); }; @@ -198,11 +227,12 @@ export function useRegisterBlocksuiteEditorCommands( onClickDelete, exportHandler, pageId, - pageMeta.title, restoreFromTrash, t, toggleFavorite, togglePageMode, trash, + isCloudWorkspace, + openHistoryModal, ]); } diff --git a/packages/frontend/core/src/hooks/affine/use-server-flavor.ts b/packages/frontend/core/src/hooks/affine/use-server-flavor.ts index 6ffb71257c..b7335d2318 100644 --- a/packages/frontend/core/src/hooks/affine/use-server-flavor.ts +++ b/packages/frontend/core/src/hooks/affine/use-server-flavor.ts @@ -12,7 +12,12 @@ const errorHandler: Middleware = useSWRNext => (key, fetcher, config) => { export const useServerFlavor = () => { const { data: config, error } = useQuery( { query: serverConfigQuery }, - { use: [errorHandler] } + { + use: [errorHandler], + revalidateOnFocus: false, + revalidateOnMount: false, + revalidateIfStale: false, + } ); if (error || !config) { diff --git a/packages/frontend/core/src/hooks/use-shortcut-commands.ts b/packages/frontend/core/src/hooks/use-browser-history-commands.ts similarity index 95% rename from packages/frontend/core/src/hooks/use-shortcut-commands.ts rename to packages/frontend/core/src/hooks/use-browser-history-commands.ts index e8003ddac8..4c3a6e810d 100644 --- a/packages/frontend/core/src/hooks/use-shortcut-commands.ts +++ b/packages/frontend/core/src/hooks/use-browser-history-commands.ts @@ -4,7 +4,7 @@ import { } from '@toeverything/infra/command'; import { useEffect } from 'react'; -export function useRegisterBlocksuiteEditorCommands( +export function useRegisterBrowserHistoryCommands( back: () => unknown, forward: () => unknown ) { diff --git a/packages/frontend/core/src/pages/workspace/detail-page.tsx b/packages/frontend/core/src/pages/workspace/detail-page.tsx index e9111cc833..58e45519ed 100644 --- a/packages/frontend/core/src/pages/workspace/detail-page.tsx +++ b/packages/frontend/core/src/pages/workspace/detail-page.tsx @@ -24,6 +24,7 @@ import { setPageModeAtom } from '../../atoms'; import { collectionsCRUDAtom } from '../../atoms/collections'; import { currentModeAtom } from '../../atoms/mode'; import { AffineErrorBoundary } from '../../components/affine/affine-error-boundary'; +import { GlobalPageHistoryModal } from '../../components/affine/page-history-modal'; import { WorkspaceHeader } from '../../components/workspace-header'; import { useRegisterBlocksuiteEditorCommands } from '../../hooks/affine/use-register-blocksuite-editor-commands'; import { useCurrentSyncEngineStatus } from '../../hooks/current/use-current-sync-engine'; @@ -41,7 +42,7 @@ const DetailPageImpl = (): ReactElement => { const { setTemporaryFilter } = useCollectionManager(collectionsCRUDAtom); const mode = useAtomValue(currentModeAtom); const setPageMode = useSetAtom(setPageModeAtom); - useRegisterBlocksuiteEditorCommands(blockSuiteWorkspace, currentPageId, mode); + useRegisterBlocksuiteEditorCommands(currentPageId, mode); const onLoad = useCallback( (page: Page, editor: EditorContainer) => { try { @@ -101,6 +102,8 @@ const DetailPageImpl = (): ReactElement => { currentPageId={currentPageId} onLoadEditor={onLoad} /> + + ); }; diff --git a/packages/frontend/graphql/src/graphql/histories.gql b/packages/frontend/graphql/src/graphql/histories.gql new file mode 100644 index 0000000000..b6aade3e0c --- /dev/null +++ b/packages/frontend/graphql/src/graphql/histories.gql @@ -0,0 +1,13 @@ +query listHistory( + $workspaceId: String! + $pageDocId: String! + $take: Int + $before: DateTime +) { + workspace(id: $workspaceId) { + histories(guid: $pageDocId, take: $take, before: $before) { + id + timestamp + } + } +} diff --git a/packages/frontend/graphql/src/graphql/index.ts b/packages/frontend/graphql/src/graphql/index.ts index 86ef26cfd1..9f543e0569 100644 --- a/packages/frontend/graphql/src/graphql/index.ts +++ b/packages/frontend/graphql/src/graphql/index.ts @@ -362,6 +362,22 @@ query getWorkspaces { }`, }; +export const listHistoryQuery = { + id: 'listHistoryQuery' as const, + operationName: 'listHistory', + definitionName: 'workspace', + containsFile: false, + query: ` +query listHistory($workspaceId: String!, $pageDocId: String!, $take: Int, $before: DateTime) { + workspace(id: $workspaceId) { + histories(guid: $pageDocId, take: $take, before: $before) { + id + timestamp + } + } +}`, +}; + export const getInvoicesCountQuery = { id: 'getInvoicesCountQuery' as const, operationName: 'getInvoicesCount', @@ -445,6 +461,17 @@ mutation publishPage($workspaceId: String!, $pageId: String!, $mode: PublicPageM }`, }; +export const recoverDocMutation = { + id: 'recoverDocMutation' as const, + operationName: 'recoverDoc', + definitionName: 'recoverDoc', + containsFile: false, + query: ` +mutation recoverDoc($workspaceId: String!, $docId: String!, $timestamp: DateTime!) { + recoverDoc(workspaceId: $workspaceId, guid: $docId, timestamp: $timestamp) +}`, +}; + export const removeAvatarMutation = { id: 'removeAvatarMutation' as const, operationName: 'removeAvatar', diff --git a/packages/frontend/graphql/src/graphql/recover-doc.gql b/packages/frontend/graphql/src/graphql/recover-doc.gql new file mode 100644 index 0000000000..d7a1dfcada --- /dev/null +++ b/packages/frontend/graphql/src/graphql/recover-doc.gql @@ -0,0 +1,7 @@ +mutation recoverDoc( + $workspaceId: String! + $docId: String! + $timestamp: DateTime! +) { + recoverDoc(workspaceId: $workspaceId, guid: $docId, timestamp: $timestamp) +} diff --git a/packages/frontend/graphql/src/schema.ts b/packages/frontend/graphql/src/schema.ts index 61b4b4020c..b0243ca909 100644 --- a/packages/frontend/graphql/src/schema.ts +++ b/packages/frontend/graphql/src/schema.ts @@ -373,6 +373,25 @@ export type GetWorkspacesQuery = { workspaces: Array<{ __typename?: 'WorkspaceType'; id: string }>; }; +export type ListHistoryQueryVariables = Exact<{ + workspaceId: Scalars['String']['input']; + pageDocId: Scalars['String']['input']; + take: InputMaybe; + before: InputMaybe; +}>; + +export type ListHistoryQuery = { + __typename?: 'Query'; + workspace: { + __typename?: 'WorkspaceType'; + histories: Array<{ + __typename?: 'DocHistoryType'; + id: string; + timestamp: string; + }>; + }; +}; + export type GetInvoicesCountQueryVariables = Exact<{ [key: string]: never }>; export type GetInvoicesCountQuery = { @@ -445,6 +464,17 @@ export type PublishPageMutation = { }; }; +export type RecoverDocMutationVariables = Exact<{ + workspaceId: Scalars['String']['input']; + docId: Scalars['String']['input']; + timestamp: Scalars['DateTime']['input']; +}>; + +export type RecoverDocMutation = { + __typename?: 'Mutation'; + recoverDoc: string; +}; + export type RemoveAvatarMutationVariables = Exact<{ [key: string]: never }>; export type RemoveAvatarMutation = { @@ -729,6 +759,11 @@ export type Queries = variables: GetWorkspacesQueryVariables; response: GetWorkspacesQuery; } + | { + name: 'listHistoryQuery'; + variables: ListHistoryQueryVariables; + response: ListHistoryQuery; + } | { name: 'getInvoicesCountQuery'; variables: GetInvoicesCountQueryVariables; @@ -816,6 +851,11 @@ export type Mutations = variables: PublishPageMutationVariables; response: PublishPageMutation; } + | { + name: 'recoverDocMutation'; + variables: RecoverDocMutationVariables; + response: RecoverDocMutation; + } | { name: 'removeAvatarMutation'; variables: RemoveAvatarMutationVariables; diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index 8bfeed413e..440de930e6 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -518,6 +518,7 @@ "com.affine.cmdk.affine.switch-state.on": "ON", "com.affine.cmdk.affine.translucent-ui-on-the-sidebar.to": "Change Translucent UI On The Sidebar to", "com.affine.cmdk.affine.whats-new": "What's New", + "com.affine.cmdk.affine.editor.reveal-page-history-modal": "Reveal Page History Modal", "com.affine.cmdk.placeholder": "Type a command or search anything...", "com.affine.collection-bar.action.tooltip.delete": "Delete", "com.affine.collection-bar.action.tooltip.edit": "Edit", @@ -972,5 +973,13 @@ "system": "System", "upgradeBrowser": "Please upgrade to the latest version of Chrome for the best experience.", "will be moved to Trash": "{{title}} will be moved to Trash", - "will delete member": "will delete member" + "will delete member": "will delete member", + "com.affine.history.version-history": "Version History", + "com.affine.history.view-history-version": "View History Version", + "com.affine.history.restore-current-version": "Restore current version", + "com.affine.history.back-to-page": "Back to page", + "com.affine.history.empty-prompt.title": "Empty", + "com.affine.history.empty-prompt.description": "This document is such a spring chicken, it hasn't sprouted a single historical sprig yet!", + "com.affine.history.confirm-restore-modal.restore": "Restore", + "com.affine.history.confirm-restore-modal.hint": "You are about to restore the current version of the page to the latest version available. This action will overwrite any changes made prior to the latest version." } diff --git a/packages/frontend/workspace/package.json b/packages/frontend/workspace/package.json index 57d5f88b5c..0662a725a9 100644 --- a/packages/frontend/workspace/package.json +++ b/packages/frontend/workspace/package.json @@ -4,6 +4,7 @@ "exports": { "./atom": "./src/atom.ts", "./manager": "./src/manager/index.ts", + "./blob": "./src/blob/index.ts", "./local/crud": "./src/local/crud.ts", "./affine/*": "./src/affine/*.ts", "./providers": "./src/providers/index.ts" diff --git a/packages/frontend/workspace/src/affine/gql.ts b/packages/frontend/workspace/src/affine/gql.ts index 102e5c7d31..b7988042a0 100644 --- a/packages/frontend/workspace/src/affine/gql.ts +++ b/packages/frontend/workspace/src/affine/gql.ts @@ -5,12 +5,15 @@ import type { QueryOptions, QueryResponse, QueryVariables, + RecursiveMaybeFields, } from '@affine/graphql'; import { gqlFetcherFactory } from '@affine/graphql'; +import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks'; import type { GraphQLError } from 'graphql'; import { useMemo } from 'react'; import type { Key, SWRConfiguration, SWRResponse } from 'swr'; -import useSWR from 'swr'; +import useSWR, { useSWRConfig } from 'swr'; +import useSWRInfinite from 'swr/infinite'; import type { SWRMutationConfiguration, SWRMutationResponse, @@ -86,6 +89,63 @@ export function useQuery( ); } +export function useQueryInfinite( + options: Omit, 'variables'> & { + getVariables: ( + pageIndex: number, + previousPageData: QueryResponse + ) => QueryOptions['variables']; + }, + config?: Omit< + SWRConfiguration< + QueryResponse, + GraphQLError | GraphQLError[], + typeof fetcher + >, + 'fetcher' + > +) { + const configWithSuspense: SWRConfiguration = useMemo( + () => ({ + suspense: true, + ...config, + }), + [config] + ); + + const { data, setSize, size, error } = useSWRInfinite< + QueryResponse, + GraphQLError | GraphQLError[] + >( + (pageIndex: number, previousPageData: QueryResponse) => [ + 'cloud', + options.query.id, + options.getVariables(pageIndex, previousPageData), + ], + async ([_, __, variables]) => { + const params = { ...options, variables } as QueryOptions; + return fetcher(params); + }, + configWithSuspense + ); + + const loadingMore = size > 0 && data && !data[size - 1]; + + // todo: find a generic way to know whether or not there are more items to load + const loadMore = useAsyncCallback(async () => { + if (loadingMore) { + return; + } + await setSize(size => size + 1); + }, [loadingMore, setSize]); + return { + data, + error, + loadingMore, + loadMore, + }; +} + /** * A useSWRMutation wrapper for sending graphql mutations * @@ -138,3 +198,32 @@ export function useMutation( } export const gql = fetcher; + +// use this to revalidate all queries that match the filter +export const useMutateQueryResource = () => { + const { mutate } = useSWRConfig(); + const revalidateResource = useMemo( + () => + ( + query: Q, + varsFilter: ( + vars: RecursiveMaybeFields> + ) => boolean = _vars => true + ) => { + return mutate(key => { + const res = + Array.isArray(key) && + key[0] === 'cloud' && + key[1] === query.id && + varsFilter(key[2]); + if (res) { + console.debug('revalidate resource', key); + } + return res; + }); + }, + [mutate] + ); + + return revalidateResource; +}; From 71d6b730f7564d7e9fa8a3576fcbcf19d81b30d7 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Mon, 27 Nov 2023 04:46:23 +0000 Subject: [PATCH 04/11] chore: bump blocksuite (#5051) https://github.com/toeverything/blocksuite/pull/5337 --- packages/common/env/package.json | 4 +- packages/common/infra/package.json | 10 +- packages/common/sdk/package.json | 10 +- packages/common/y-indexeddb/package.json | 4 +- packages/common/y-provider/package.json | 2 +- packages/frontend/component/package.json | 10 +- packages/frontend/core/package.json | 14 +- packages/frontend/electron/package.json | 8 +- packages/frontend/hooks/package.json | 12 +- tests/affine-legacy/0.6.1-beta.1/package.json | 8 +- .../0.7.0-canary.18/package.json | 8 +- .../affine-legacy/0.8.0-canary.7/package.json | 8 +- tests/affine-legacy/0.8.4/package.json | 8 +- tests/affine-migration/package.json | 8 +- tests/storybook/package.json | 14 +- yarn.lock | 360 +++++++++--------- 16 files changed, 250 insertions(+), 238 deletions(-) diff --git a/packages/common/env/package.json b/packages/common/env/package.json index 35178ae591..0f1ba316dc 100644 --- a/packages/common/env/package.json +++ b/packages/common/env/package.json @@ -3,8 +3,8 @@ "private": true, "type": "module", "devDependencies": { - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "react": "18.2.0", "react-dom": "18.2.0", "vitest": "0.34.6", diff --git a/packages/common/infra/package.json b/packages/common/infra/package.json index 81a7c8e31a..4de352fd34 100644 --- a/packages/common/infra/package.json +++ b/packages/common/infra/package.json @@ -55,9 +55,9 @@ }, "dependencies": { "@affine/sdk": "workspace:*", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "jotai": "^2.5.1", "jotai-effect": "^0.2.3", "tinykeys": "^2.1.0", @@ -66,8 +66,8 @@ "devDependencies": { "@affine-test/fixtures": "workspace:*", "@affine/templates": "workspace:*", - "@blocksuite/editor": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/lit": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/editor": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/lit": "0.0.0-20231124123613-7c06e95d-nightly", "@testing-library/react": "^14.0.0", "async-call-rpc": "^6.3.1", "electron": "link:../../frontend/electron/node_modules/electron", diff --git a/packages/common/sdk/package.json b/packages/common/sdk/package.json index 574a769c88..2f25006092 100644 --- a/packages/common/sdk/package.json +++ b/packages/common/sdk/package.json @@ -22,11 +22,11 @@ "dist" ], "dependencies": { - "@blocksuite/block-std": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/editor": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/block-std": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/editor": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "jotai": "^2.5.1", "zod": "^3.22.4" }, diff --git a/packages/common/y-indexeddb/package.json b/packages/common/y-indexeddb/package.json index 3dc95f92f7..28bb651424 100644 --- a/packages/common/y-indexeddb/package.json +++ b/packages/common/y-indexeddb/package.json @@ -37,8 +37,8 @@ "y-provider": "workspace:*" }, "devDependencies": { - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "fake-indexeddb": "^5.0.0", "vite": "^4.4.11", "vite-plugin-dts": "3.6.0", diff --git a/packages/common/y-provider/package.json b/packages/common/y-provider/package.json index 8ec4e93f62..d56d14de84 100644 --- a/packages/common/y-provider/package.json +++ b/packages/common/y-provider/package.json @@ -24,7 +24,7 @@ "build": "vite build" }, "devDependencies": { - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "vite": "^4.4.11", "vite-plugin-dts": "3.6.0", "vitest": "0.34.6", diff --git a/packages/frontend/component/package.json b/packages/frontend/component/package.json index 08976bb9a3..118be62427 100644 --- a/packages/frontend/component/package.json +++ b/packages/frontend/component/package.json @@ -64,12 +64,12 @@ "uuid": "^9.0.1" }, "devDependencies": { - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/editor": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/editor": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", "@blocksuite/icons": "2.1.36", - "@blocksuite/lit": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/lit": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "@storybook/jest": "^0.2.3", "@storybook/testing-library": "^0.2.2", "@testing-library/react": "^14.0.0", diff --git a/packages/frontend/core/package.json b/packages/frontend/core/package.json index 87660c3037..bf31b42040 100644 --- a/packages/frontend/core/package.json +++ b/packages/frontend/core/package.json @@ -25,14 +25,14 @@ "@affine/i18n": "workspace:*", "@affine/templates": "workspace:*", "@affine/workspace": "workspace:*", - "@blocksuite/block-std": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/editor": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/block-std": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/editor": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", "@blocksuite/icons": "2.1.36", - "@blocksuite/lit": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/virgo": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/lit": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/virgo": "0.0.0-20231124123613-7c06e95d-nightly", "@dnd-kit/core": "^6.0.8", "@dnd-kit/sortable": "^8.0.0", "@emotion/cache": "^11.11.0", diff --git a/packages/frontend/electron/package.json b/packages/frontend/electron/package.json index a844b4e763..b2345694ed 100644 --- a/packages/frontend/electron/package.json +++ b/packages/frontend/electron/package.json @@ -32,10 +32,10 @@ "@affine/sdk": "workspace:*", "@affine/templates": "workspace:*", "@affine/vue-hello-world-plugin": "workspace:*", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/editor": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/lit": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/editor": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/lit": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "@electron-forge/cli": "^7.1.0", "@electron-forge/core": "^7.1.0", "@electron-forge/core-utils": "^7.1.0", diff --git a/packages/frontend/hooks/package.json b/packages/frontend/hooks/package.json index 38cee5bcc9..e409597eef 100644 --- a/packages/frontend/hooks/package.json +++ b/packages/frontend/hooks/package.json @@ -18,12 +18,12 @@ "devDependencies": { "@affine/debug": "workspace:*", "@affine/env": "workspace:*", - "@blocksuite/block-std": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/editor": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/lit": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/block-std": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/editor": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/lit": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "@testing-library/react": "^14.0.0", "@types/image-blob-reduce": "^4.1.3", "@types/lodash.debounce": "^4.0.7", diff --git a/tests/affine-legacy/0.6.1-beta.1/package.json b/tests/affine-legacy/0.6.1-beta.1/package.json index 1b1371d47c..93313fd020 100644 --- a/tests/affine-legacy/0.6.1-beta.1/package.json +++ b/tests/affine-legacy/0.6.1-beta.1/package.json @@ -9,10 +9,10 @@ "devDependencies": { "@affine-test/fixtures": "workspace:*", "@affine-test/kit": "workspace:*", - "@blocksuite/block-std": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/block-std": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "@playwright/test": "^1.39.0", "express": "^4.18.2", "http-proxy-middleware": "^3.0.0-beta.1", diff --git a/tests/affine-legacy/0.7.0-canary.18/package.json b/tests/affine-legacy/0.7.0-canary.18/package.json index 7d340e4ae3..5cc05369dd 100644 --- a/tests/affine-legacy/0.7.0-canary.18/package.json +++ b/tests/affine-legacy/0.7.0-canary.18/package.json @@ -9,10 +9,10 @@ "devDependencies": { "@affine-test/fixtures": "workspace:*", "@affine-test/kit": "workspace:*", - "@blocksuite/block-std": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/block-std": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "@playwright/test": "^1.39.0", "express": "^4.18.2", "http-proxy-middleware": "^3.0.0-beta.1", diff --git a/tests/affine-legacy/0.8.0-canary.7/package.json b/tests/affine-legacy/0.8.0-canary.7/package.json index 4c08240dda..5288701014 100644 --- a/tests/affine-legacy/0.8.0-canary.7/package.json +++ b/tests/affine-legacy/0.8.0-canary.7/package.json @@ -9,10 +9,10 @@ "devDependencies": { "@affine-test/fixtures": "workspace:*", "@affine-test/kit": "workspace:*", - "@blocksuite/block-std": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/block-std": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "@playwright/test": "^1.39.0", "express": "^4.18.2", "http-proxy-middleware": "^3.0.0-beta.1", diff --git a/tests/affine-legacy/0.8.4/package.json b/tests/affine-legacy/0.8.4/package.json index 00a2b9ec07..880b598e7d 100644 --- a/tests/affine-legacy/0.8.4/package.json +++ b/tests/affine-legacy/0.8.4/package.json @@ -9,10 +9,10 @@ "devDependencies": { "@affine-test/fixtures": "workspace:*", "@affine-test/kit": "workspace:*", - "@blocksuite/block-std": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/block-std": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "@playwright/test": "^1.39.0", "express": "^4.18.2", "http-proxy-middleware": "^3.0.0-beta.1", diff --git a/tests/affine-migration/package.json b/tests/affine-migration/package.json index 9fc4523606..d73916db6b 100644 --- a/tests/affine-migration/package.json +++ b/tests/affine-migration/package.json @@ -7,10 +7,10 @@ "devDependencies": { "@affine-test/fixtures": "workspace:*", "@affine-test/kit": "workspace:*", - "@blocksuite/block-std": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/block-std": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", "@playwright/test": "^1.39.0" }, "version": "0.10.3-canary.2" diff --git a/tests/storybook/package.json b/tests/storybook/package.json index b45e83904b..94ea1225aa 100644 --- a/tests/storybook/package.json +++ b/tests/storybook/package.json @@ -31,14 +31,14 @@ "wait-on": "^7.2.0" }, "devDependencies": { - "@blocksuite/block-std": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/blocks": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/editor": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/global": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/block-std": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/blocks": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/editor": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/global": "0.0.0-20231124123613-7c06e95d-nightly", "@blocksuite/icons": "2.1.36", - "@blocksuite/lit": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/store": "0.0.0-20231122113751-6bf81eb3-nightly", - "@blocksuite/virgo": "0.0.0-20231122113751-6bf81eb3-nightly", + "@blocksuite/lit": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/store": "0.0.0-20231124123613-7c06e95d-nightly", + "@blocksuite/virgo": "0.0.0-20231124123613-7c06e95d-nightly", "@dnd-kit/sortable": "^8.0.0", "@tomfreudenberg/next-auth-mock": "^0.5.6", "chromatic": "^9.1.0", diff --git a/yarn.lock b/yarn.lock index 7ecfc155b2..e2b2110adb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,10 +25,10 @@ __metadata: dependencies: "@affine-test/fixtures": "workspace:*" "@affine-test/kit": "workspace:*" - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@playwright/test": "npm:^1.39.0" express: "npm:^4.18.2" http-proxy-middleware: "npm:^3.0.0-beta.1" @@ -42,10 +42,10 @@ __metadata: dependencies: "@affine-test/fixtures": "workspace:*" "@affine-test/kit": "workspace:*" - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@playwright/test": "npm:^1.39.0" express: "npm:^4.18.2" http-proxy-middleware: "npm:^3.0.0-beta.1" @@ -59,10 +59,10 @@ __metadata: dependencies: "@affine-test/fixtures": "workspace:*" "@affine-test/kit": "workspace:*" - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@playwright/test": "npm:^1.39.0" express: "npm:^4.18.2" http-proxy-middleware: "npm:^3.0.0-beta.1" @@ -76,10 +76,10 @@ __metadata: dependencies: "@affine-test/fixtures": "workspace:*" "@affine-test/kit": "workspace:*" - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@playwright/test": "npm:^1.39.0" express: "npm:^4.18.2" http-proxy-middleware: "npm:^3.0.0-beta.1" @@ -138,10 +138,10 @@ __metadata: dependencies: "@affine-test/fixtures": "workspace:*" "@affine-test/kit": "workspace:*" - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@playwright/test": "npm:^1.39.0" languageName: unknown linkType: soft @@ -212,12 +212,12 @@ __metadata: "@affine/graphql": "workspace:*" "@affine/i18n": "workspace:*" "@affine/workspace": "workspace:*" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/editor": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/editor": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@blocksuite/icons": "npm:2.1.36" - "@blocksuite/lit": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/lit": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@dnd-kit/core": "npm:^6.0.8" "@dnd-kit/modifiers": "npm:^6.0.1" "@dnd-kit/sortable": "npm:^8.0.0" @@ -325,14 +325,14 @@ __metadata: "@affine/templates": "workspace:*" "@affine/workspace": "workspace:*" "@aws-sdk/client-s3": "npm:3.433.0" - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/editor": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/editor": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@blocksuite/icons": "npm:2.1.36" - "@blocksuite/lit": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/virgo": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/lit": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/virgo": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@dnd-kit/core": "npm:^6.0.8" "@dnd-kit/sortable": "npm:^8.0.0" "@emotion/cache": "npm:^11.11.0" @@ -437,10 +437,10 @@ __metadata: "@affine/sdk": "workspace:*" "@affine/templates": "workspace:*" "@affine/vue-hello-world-plugin": "workspace:*" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/editor": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/lit": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/editor": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/lit": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@electron-forge/cli": "npm:^7.1.0" "@electron-forge/core": "npm:^7.1.0" "@electron-forge/core-utils": "npm:^7.1.0" @@ -488,8 +488,8 @@ __metadata: version: 0.0.0-use.local resolution: "@affine/env@workspace:packages/common/env" dependencies: - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" lit: "npm:^3.0.2" react: "npm:18.2.0" react-dom: "npm:18.2.0" @@ -685,11 +685,11 @@ __metadata: version: 0.0.0-use.local resolution: "@affine/sdk@workspace:packages/common/sdk" dependencies: - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/editor": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/editor": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" jotai: "npm:^2.5.1" vite: "npm:^4.4.11" vite-plugin-dts: "npm:3.6.0" @@ -812,14 +812,14 @@ __metadata: dependencies: "@affine/component": "workspace:*" "@affine/i18n": "workspace:*" - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/editor": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/editor": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@blocksuite/icons": "npm:2.1.36" - "@blocksuite/lit": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/virgo": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/lit": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/virgo": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@dnd-kit/sortable": "npm:^8.0.0" "@storybook/addon-actions": "npm:^7.5.3" "@storybook/addon-essentials": "npm:^7.5.3" @@ -4060,31 +4060,31 @@ __metadata: languageName: node linkType: hard -"@blocksuite/block-std@npm:0.0.0-20231122113751-6bf81eb3-nightly": - version: 0.0.0-20231122113751-6bf81eb3-nightly - resolution: "@blocksuite/block-std@npm:0.0.0-20231122113751-6bf81eb3-nightly" +"@blocksuite/block-std@npm:0.0.0-20231124123613-7c06e95d-nightly": + version: 0.0.0-20231124123613-7c06e95d-nightly + resolution: "@blocksuite/block-std@npm:0.0.0-20231124123613-7c06e95d-nightly" dependencies: - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" lz-string: "npm:^1.5.0" w3c-keyname: "npm:^2.2.8" zod: "npm:^3.22.4" peerDependencies: - "@blocksuite/store": 0.0.0-20231122113751-6bf81eb3-nightly - checksum: 0b75b090cd676cc8ca5972fad73d1afa75f2624e9bf1c21f2b770bf9272b592f3b90e6d6e26695d4512c0c0c38f139199420525b68258d954281c89e7785fb45 + "@blocksuite/store": 0.0.0-20231124123613-7c06e95d-nightly + checksum: c2fbfdc60c8a6e2c38b8b572522d70543ae89b66283d8e246b8058eb6c8de83ede739dcfd5df204434147eefadbf0aeabc0bd26eb064f2fb771b8bfc32fc5443 languageName: node linkType: hard -"@blocksuite/blocks@npm:0.0.0-20231122113751-6bf81eb3-nightly": - version: 0.0.0-20231122113751-6bf81eb3-nightly - resolution: "@blocksuite/blocks@npm:0.0.0-20231122113751-6bf81eb3-nightly" +"@blocksuite/blocks@npm:0.0.0-20231124123613-7c06e95d-nightly": + version: 0.0.0-20231124123613-7c06e95d-nightly + resolution: "@blocksuite/blocks@npm:0.0.0-20231124123613-7c06e95d-nightly" dependencies: - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/lit": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/virgo": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/lit": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/virgo": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@floating-ui/dom": "npm:^1.5.3" - "@toeverything/theme": "npm:^0.7.24" + "@toeverything/theme": "npm:^0.7.26" "@types/webfontloader": "npm:^1.6.36" buffer: "npm:^6.0.3" date-fns: "npm:^2.30.0" @@ -4100,30 +4100,30 @@ __metadata: sortablejs: "npm:^1.15.0" webfontloader: "npm:^1.6.28" zod: "npm:^3.22.4" - checksum: eab05e86fbe9a0e5b10d82ff6867af3a2987f56e5e5656874149d656ec3cecda0b5870ab59340e0f50c22843bc5f3fb7af3cb0399b8c65f58d76e02a1a08d2af + checksum: d08b8fae9fd7d5b64d1c0a7f2278ae71608848c9df16aa52be69818868e71ff0d1abf9bd082395e6ec3ccb97ea32e8e3f9483bfec46941105366125a4c2751f3 languageName: node linkType: hard -"@blocksuite/editor@npm:0.0.0-20231122113751-6bf81eb3-nightly": - version: 0.0.0-20231122113751-6bf81eb3-nightly - resolution: "@blocksuite/editor@npm:0.0.0-20231122113751-6bf81eb3-nightly" +"@blocksuite/editor@npm:0.0.0-20231124123613-7c06e95d-nightly": + version: 0.0.0-20231124123613-7c06e95d-nightly + resolution: "@blocksuite/editor@npm:0.0.0-20231124123613-7c06e95d-nightly" dependencies: - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/lit": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@toeverything/theme": "npm:^0.7.24" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/lit": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@toeverything/theme": "npm:^0.7.26" lit: "npm:^3.0.2" - checksum: 2792e80cc253926f5399d8e737ec6553a69ce74b1a881f4f7f5a8aeeb9ef54fe676a8bb522171f064b2f0638a551e1bbfd49668c63f810b23144313171809e47 + checksum: 9da41777250311c926c65a4d8812dc9b43709b3822859617542c6ea6afc5092df1a28d37c228e16c8d0089ff2565aadc3ff234f51429f9366e93b8c21bb4aaf3 languageName: node linkType: hard -"@blocksuite/global@npm:0.0.0-20231122113751-6bf81eb3-nightly": - version: 0.0.0-20231122113751-6bf81eb3-nightly - resolution: "@blocksuite/global@npm:0.0.0-20231122113751-6bf81eb3-nightly" +"@blocksuite/global@npm:0.0.0-20231124123613-7c06e95d-nightly": + version: 0.0.0-20231124123613-7c06e95d-nightly + resolution: "@blocksuite/global@npm:0.0.0-20231124123613-7c06e95d-nightly" dependencies: zod: "npm:^3.22.4" - checksum: ef0e6649c29290e4eb510cf019e83f0dcc0febc3b1cae24c982f20889534333ef44886f53a97540eb1c364c4eb4591ddf45cca4bcf6fbbe4fe15175bcc19eba2 + checksum: 739e00a63011212a9b74c6af913b6d6d73b3cf2b75fd8abd2680635bb295515f1634ae535334f10d10a8c670e641e5098040c8b5f9d77abdc900bcc058232d03 languageName: node linkType: hard @@ -4137,26 +4137,26 @@ __metadata: languageName: node linkType: hard -"@blocksuite/lit@npm:0.0.0-20231122113751-6bf81eb3-nightly": - version: 0.0.0-20231122113751-6bf81eb3-nightly - resolution: "@blocksuite/lit@npm:0.0.0-20231122113751-6bf81eb3-nightly" +"@blocksuite/lit@npm:0.0.0-20231124123613-7c06e95d-nightly": + version: 0.0.0-20231124123613-7c06e95d-nightly + resolution: "@blocksuite/lit@npm:0.0.0-20231124123613-7c06e95d-nightly" dependencies: - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/virgo": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/virgo": "npm:0.0.0-20231124123613-7c06e95d-nightly" lit: "npm:^3.0.2" peerDependencies: - "@blocksuite/block-std": 0.0.0-20231122113751-6bf81eb3-nightly - "@blocksuite/store": 0.0.0-20231122113751-6bf81eb3-nightly - checksum: 1a3d2d27823ecde0ca7453fe0d4216fa39b8623f0306486972e618b2ed9dd22f6b53a58e699f82ccc63cc001af113969eb3fa23ce7016a79d77c55d54fa8705c + "@blocksuite/block-std": 0.0.0-20231124123613-7c06e95d-nightly + "@blocksuite/store": 0.0.0-20231124123613-7c06e95d-nightly + checksum: 8ce5fa1918cf1a39cb8922ba39a4c4248690350a258bf6fdae9f098de7ca9fd45762ee994781626bdea76a02697c2bb972044a02b33ab45f1aecec6ce94260e0 languageName: node linkType: hard -"@blocksuite/store@npm:0.0.0-20231122113751-6bf81eb3-nightly": - version: 0.0.0-20231122113751-6bf81eb3-nightly - resolution: "@blocksuite/store@npm:0.0.0-20231122113751-6bf81eb3-nightly" +"@blocksuite/store@npm:0.0.0-20231124123613-7c06e95d-nightly": + version: 0.0.0-20231124123613-7c06e95d-nightly + resolution: "@blocksuite/store@npm:0.0.0-20231124123613-7c06e95d-nightly" dependencies: - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/virgo": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/virgo": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@types/flexsearch": "npm:^0.7.3" "@types/mdast": "npm:^4.0.2" flexsearch: "npm:0.7.21" @@ -4174,20 +4174,20 @@ __metadata: peerDependencies: async-call-rpc: ^6 yjs: ^13 - checksum: 97132a465bb37383b851a278826e7ffd6e6b9dfdc64d3d34887c6837b432f0ed77816701d6f97f719896b48c6f259882cda429f1c6dff9de5ba0065d4a3b468e + checksum: fb993b2db0f3720c972a341923a6215fb86d2cb48812cc8fc7aecdb04ba2b904236271d18d796e9a7a5eb1a303dc516f91bc78e76d8fa94af1cee3016fb68f73 languageName: node linkType: hard -"@blocksuite/virgo@npm:0.0.0-20231122113751-6bf81eb3-nightly": - version: 0.0.0-20231122113751-6bf81eb3-nightly - resolution: "@blocksuite/virgo@npm:0.0.0-20231122113751-6bf81eb3-nightly" +"@blocksuite/virgo@npm:0.0.0-20231124123613-7c06e95d-nightly": + version: 0.0.0-20231124123613-7c06e95d-nightly + resolution: "@blocksuite/virgo@npm:0.0.0-20231124123613-7c06e95d-nightly" dependencies: - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" zod: "npm:^3.22.4" peerDependencies: lit: ^3.0.2 yjs: ^13 - checksum: a18e632590306cf14c02e6d308b8604532dc7cb1085d53a99857076768eabc6999b677d0e1ba225051d75f7915cc5a4954d4a303fd459436a7b5a902dbd7b7f1 + checksum: 02732e5ff5c4206e23f473c467c5b786f646af6b67c44bb38f2faf70525513e9571c9b640ff8a20fba221968c0dfd5d05391761d57b297970b9d77eb3aa21b14 languageName: node linkType: hard @@ -6420,20 +6420,20 @@ __metadata: linkType: hard "@graphql-tools/load@npm:^8.0.0": - version: 8.0.0 - resolution: "@graphql-tools/load@npm:8.0.0" + version: 8.0.1 + resolution: "@graphql-tools/load@npm:8.0.1" dependencies: "@graphql-tools/schema": "npm:^10.0.0" - "@graphql-tools/utils": "npm:^10.0.0" + "@graphql-tools/utils": "npm:^10.0.11" p-limit: "npm:3.1.0" tslib: "npm:^2.4.0" peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 64bbcaae28bf895f0d1f0636325a5b567cca1524ffd02bcad58a063087e74c65b9c1a5743adc2cc18a4f3c0379f7426090f8784abcddfd60997f187e6f100eb4 + checksum: 008acefaaa067b4de26321803a9e95749ac39a009fe2614a2b39ce331efc858e0c3fe2de098b0b486fff857d061a164cbf0da479e03671fc9aaab1b882cf003e languageName: node linkType: hard -"@graphql-tools/merge@npm:9.0.0, @graphql-tools/merge@npm:^9.0.0": +"@graphql-tools/merge@npm:9.0.0": version: 9.0.0 resolution: "@graphql-tools/merge@npm:9.0.0" dependencies: @@ -6457,6 +6457,18 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/merge@npm:^9.0.0, @graphql-tools/merge@npm:^9.0.1": + version: 9.0.1 + resolution: "@graphql-tools/merge@npm:9.0.1" + dependencies: + "@graphql-tools/utils": "npm:^10.0.10" + tslib: "npm:^2.4.0" + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 9c2e57a0eee07b568c4c781303947e4c633f1dff54ba23a449965ecdf3301d97d14ba071479e0d46e3c142ee552daf834a798a1cf57a6b846f9d055c703a4e16 + languageName: node + linkType: hard + "@graphql-tools/optimize@npm:^2.0.0": version: 2.0.0 resolution: "@graphql-tools/optimize@npm:2.0.0" @@ -6524,16 +6536,16 @@ __metadata: linkType: hard "@graphql-tools/schema@npm:^10.0.0": - version: 10.0.1 - resolution: "@graphql-tools/schema@npm:10.0.1" + version: 10.0.2 + resolution: "@graphql-tools/schema@npm:10.0.2" dependencies: - "@graphql-tools/merge": "npm:^9.0.0" - "@graphql-tools/utils": "npm:^10.0.9" + "@graphql-tools/merge": "npm:^9.0.1" + "@graphql-tools/utils": "npm:^10.0.10" tslib: "npm:^2.4.0" value-or-promise: "npm:^1.0.12" peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 314283995b9e83a398dbd8b46be00056d1737d60868b88732fa651902d914f8458901efda64a976d53ff6498e4f023dfa47ed80eb451d03e5d2dda8aea42ed8b + checksum: ce9ddf9ed446c9d421d0601b226315a10339b629f2a47ae39690ee3684ec759c4784e4d45a02c84de18a39478c217399d7852b086e5c18046b45b40ea18c4ccd languageName: node linkType: hard @@ -6588,9 +6600,9 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/utils@npm:^10.0.0, @graphql-tools/utils@npm:^10.0.2, @graphql-tools/utils@npm:^10.0.5, @graphql-tools/utils@npm:^10.0.8, @graphql-tools/utils@npm:^10.0.9": - version: 10.0.9 - resolution: "@graphql-tools/utils@npm:10.0.9" +"@graphql-tools/utils@npm:^10.0.0, @graphql-tools/utils@npm:^10.0.10, @graphql-tools/utils@npm:^10.0.11, @graphql-tools/utils@npm:^10.0.2, @graphql-tools/utils@npm:^10.0.5, @graphql-tools/utils@npm:^10.0.8": + version: 10.0.11 + resolution: "@graphql-tools/utils@npm:10.0.11" dependencies: "@graphql-typed-document-node/core": "npm:^3.1.1" cross-inspect: "npm:1.0.0" @@ -6598,7 +6610,7 @@ __metadata: tslib: "npm:^2.4.0" peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: f11e4b3289bf4c48c25e2dfbb53bb59395a4599c75234e4bb9a9bbe6d28469a3ae2248bf3c9705ed354e47817cdff7abdb6e66adcabcba6cb4a58eafe96d6fc1 + checksum: 37515aa8fa6cd85a7c3ca7e174017abffb558b8110f18f261bd8c2074b1496d764ac19b3015f9030d6dbe3235e259665bc36652a4aab8064ff75d7120887c7cc languageName: node linkType: hard @@ -10727,10 +10739,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.12.0": - version: 1.12.0 - resolution: "@remix-run/router@npm:1.12.0" - checksum: f984e42cfe855991e1d3067f686f857614f12e8c1c45168a2d98e3fc3a427e232fd0b6cf145173b7cd132faf070702b532c34230a825d933908c54c85077fc69 +"@remix-run/router@npm:1.13.0": + version: 1.13.0 + resolution: "@remix-run/router@npm:1.13.0" + checksum: bb173a012d2036c5ee69babfe30c73975b970c2e5a0edaba138c302ae80d255e238e462e77365ab4efe819b6397e1a7f3a416d6200d17f9655f0ca1c51c4f45e languageName: node linkType: hard @@ -12262,11 +12274,11 @@ __metadata: linkType: hard "@storybook/csf@npm:^0.1.0, @storybook/csf@npm:^0.1.1": - version: 0.1.1 - resolution: "@storybook/csf@npm:0.1.1" + version: 0.1.2 + resolution: "@storybook/csf@npm:0.1.2" dependencies: type-fest: "npm:^2.19.0" - checksum: d79f9eca1184a3e3e6cf6b19b47ea2378db3fb2ec574686d311597b0de83cd8148a038311a891a348089edac2dc4dd7ceb65a87845a882546d9fc00146e3ce29 + checksum: 11168df65e7b6bd0e5d31e7e805c8ba80397fc190cb33424e043b72bbd85d8f826dba082503992d7f606b72484337ab9d091eca947550613e241fbef57780d4c languageName: node linkType: hard @@ -13009,12 +13021,12 @@ __metadata: dependencies: "@affine/debug": "workspace:*" "@affine/env": "workspace:*" - "@blocksuite/block-std": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/editor": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/lit": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/block-std": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/editor": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/lit": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@testing-library/react": "npm:^14.0.0" "@types/image-blob-reduce": "npm:^4.1.3" "@types/lodash.debounce": "npm:^4.0.7" @@ -13061,11 +13073,11 @@ __metadata: "@affine-test/fixtures": "workspace:*" "@affine/sdk": "workspace:*" "@affine/templates": "workspace:*" - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/editor": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/global": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/lit": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/editor": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/global": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/lit": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" "@testing-library/react": "npm:^14.0.0" async-call-rpc: "npm:^6.3.1" electron: "link:../../frontend/electron/node_modules/electron" @@ -13103,10 +13115,10 @@ __metadata: languageName: unknown linkType: soft -"@toeverything/theme@npm:^0.7.20, @toeverything/theme@npm:^0.7.24": - version: 0.7.26 - resolution: "@toeverything/theme@npm:0.7.26" - checksum: be895af99318af5ea2d624a78b4c8b7d0ce3cf00e825a593e75d2e3c3c394fd0501213f99968424021462d10d89bdb3a66a7f50e2e6a6e1c8981513b4b15ad72 +"@toeverything/theme@npm:^0.7.20, @toeverything/theme@npm:^0.7.24, @toeverything/theme@npm:^0.7.26": + version: 0.7.27 + resolution: "@toeverything/theme@npm:0.7.27" + checksum: 9349d30256d33b5528441dbca09387819225449f97549585b92b33e354d7fbb3d0e5e35001c89b8a7e3033d8f51d3aee75ef9edaaf14fb7dd717dd66bfe96009 languageName: node linkType: hard @@ -13114,8 +13126,8 @@ __metadata: version: 0.0.0-use.local resolution: "@toeverything/y-indexeddb@workspace:packages/common/y-indexeddb" dependencies: - "@blocksuite/blocks": "npm:0.0.0-20231122113751-6bf81eb3-nightly" - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/blocks": "npm:0.0.0-20231124123613-7c06e95d-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" fake-indexeddb: "npm:^5.0.0" idb: "npm:^7.1.1" nanoid: "npm:^5.0.3" @@ -13913,20 +13925,20 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=10.0.0, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0, @types/node@npm:>=8.1.0, @types/node@npm:^20.9.3": - version: 20.9.4 - resolution: "@types/node@npm:20.9.4" + version: 20.10.0 + resolution: "@types/node@npm:20.10.0" dependencies: undici-types: "npm:~5.26.4" - checksum: d567855b48e453b443499c17fc6c939d154732b54319a05b9b31db6e475e6458f053838635b201b1bb493d349d9b1af0aecc58b28fd6062e564e9fbf593199eb + checksum: c7d5ddbdbf3491e2363135c9611eb6bfae90eda2957279237fa232bcb29cd0df1cc3ee149d6de9915b754262a531ee2d57d33c9ecd58d763e8ad4856113822f3 languageName: node linkType: hard "@types/node@npm:^18.0.0, @types/node@npm:^18.11.18, @types/node@npm:^18.11.9": - version: 18.18.12 - resolution: "@types/node@npm:18.18.12" + version: 18.18.13 + resolution: "@types/node@npm:18.18.13" dependencies: undici-types: "npm:~5.26.4" - checksum: bd32120a52e7bdbf38dafa0f9cdb0c322115fc7fe38890b6c151507199d307652905077b878f0173c375389c87400d78f25a12fc8517b8f829547c95df37ef4e + checksum: 5dcab799e39570a858741a13373a584529d0e6b81120c8a2118e158749d9ace291748644d760af554fe73ab3cebdd91500314bf1ecd17a746fabcae06ebf9eea languageName: node linkType: hard @@ -15159,15 +15171,15 @@ __metadata: linkType: hard "@whatwg-node/node-fetch@npm:^0.5.0": - version: 0.5.0 - resolution: "@whatwg-node/node-fetch@npm:0.5.0" + version: 0.5.1 + resolution: "@whatwg-node/node-fetch@npm:0.5.1" dependencies: "@whatwg-node/events": "npm:^0.1.0" busboy: "npm:^1.6.0" fast-querystring: "npm:^1.1.1" fast-url-parser: "npm:^1.1.3" tslib: "npm:^2.3.1" - checksum: b779288b07296e0be60e90e338de46b9d0c892d2e38b99bd04d062bbd4acb429607afc92b9bfdbf10841cef6f4b531e63415197583677de69a07e7b2e39350b9 + checksum: 7e630fe252dea7fb8c844e8643510e819d7b803649b709ee9ffd663870cc6715302f7a32b934c9cc6a9568f657d322173dfa66dd28ba2bd026014bf1f8bfcd33 languageName: node linkType: hard @@ -19592,9 +19604,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.4.535": - version: 1.4.590 - resolution: "electron-to-chromium@npm:1.4.590" - checksum: 04f54be67d5465432363e6a7cf0813dbd95a23d115f55679662677508d9e068ce241b4a8e1224a53fccc4037094928d38946529c5118c1184090e2609c65cd94 + version: 1.4.593 + resolution: "electron-to-chromium@npm:1.4.593" + checksum: 836463303815c1e599183e4cd84549b76c1451602c68119bfd428f706202c7d2e799cdbf1408e2d154155f84bc85020491b3244b2f5a29614d96fa7d6967b114 languageName: node linkType: hard @@ -19644,15 +19656,15 @@ __metadata: linkType: soft "electron@npm:^27.1.0": - version: 27.1.0 - resolution: "electron@npm:27.1.0" + version: 27.1.2 + resolution: "electron@npm:27.1.2" dependencies: "@electron/get": "npm:^2.0.0" "@types/node": "npm:^18.11.18" extract-zip: "npm:^2.0.1" bin: electron: cli.js - checksum: 8eed880bbda6efd55041cc855b93f632897139557761a913dd56c68a9e24bcb1c222a0b335f70e3df97e9692997f659d62600276bbf3714b374d841fed75bab4 + checksum: c24cbdee2ea7e219d2224e3b3f9760a248723490442dcdf28a5c5419c693127bc0ab169945bd6e7ff7db84c69b3ed4db65e2691dd2f7e15b2b0eea905a1e8863 languageName: node linkType: hard @@ -26224,9 +26236,9 @@ __metadata: linkType: hard "lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": - version: 10.0.3 - resolution: "lru-cache@npm:10.0.3" - checksum: 2fd14d8f828760eb4f1e696d20383bf52bb58a02aebfd08cb8035a66876c6fc1ec244ffdcf93d5a201fdad6d9f8c59de62c4fc5ff5604d67a4f833441f5b5945 + version: 10.1.0 + resolution: "lru-cache@npm:10.1.0" + checksum: 207278d6fa711fb1f94a0835d4d4737441d2475302482a14785b10515e4c906a57ebf9f35bf060740c9560e91c7c1ad5a04fd7ed030972a9ba18bce2a228e95b languageName: node linkType: hard @@ -30966,26 +30978,26 @@ __metadata: linkType: hard "react-router-dom@npm:^6.16.0, react-router-dom@npm:^6.19.0": - version: 6.19.0 - resolution: "react-router-dom@npm:6.19.0" + version: 6.20.0 + resolution: "react-router-dom@npm:6.20.0" dependencies: - "@remix-run/router": "npm:1.12.0" - react-router: "npm:6.19.0" + "@remix-run/router": "npm:1.13.0" + react-router: "npm:6.20.0" peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: 38312efc11d3ef688062301479a8257a1495a81cd8dd7039c1f81aba6774963df7d21aaee2ba1a3c152857b70f4fb9966a3ccff47aca12212e854dcd6fc4deab + checksum: 4b6741c545cedf5a5c4f996deb953679dcc985425e0664e27b97fdb9ab1387cbe1a6a12bfc7f7c38ec40b15759b4bf6396930ec26540a4a81ae16d154fd35049 languageName: node linkType: hard -"react-router@npm:6.19.0": - version: 6.19.0 - resolution: "react-router@npm:6.19.0" +"react-router@npm:6.20.0": + version: 6.20.0 + resolution: "react-router@npm:6.20.0" dependencies: - "@remix-run/router": "npm:1.12.0" + "@remix-run/router": "npm:1.13.0" peerDependencies: react: ">=16.8" - checksum: 5454f4a4d65401430ded8f1033cebe4ccca771c3c827e8329c77dcfd73618ca9a32488fb58722bf6a07afef7d8e7ef22a710aae0f3337e5c20962bf6473d81a3 + checksum: 2cdac5ad8b7a7bc230173b26768bcf3f6a9abc0a19983fa7b76b9ffdbeb44bfbd88fcc2033e9062defafef144db207859eb3162a9c9742d70cfce4e7166ff1e5 languageName: node linkType: hard @@ -33902,9 +33914,9 @@ __metadata: linkType: hard "tocbot@npm:^4.20.1": - version: 4.22.0 - resolution: "tocbot@npm:4.22.0" - checksum: 41ff72948464c3d1ce6f63845c9ba1ddad11f94f25f3c22cfbbac6339ab912efc874144046fd85501c1f2e7194da3750151d7846e07b68e7663fbaed703a2163 + version: 4.23.0 + resolution: "tocbot@npm:4.23.0" + checksum: 883c7ef6baa9cd04ebb0b3ce9109f952212d695eb2ed5a44a1013a62922325f7a9b8ca8a91ad744cd717cebcb75fd94c7969d841707ea123caba4447497557f2 languageName: node linkType: hard @@ -34401,11 +34413,11 @@ __metadata: linkType: hard "undici@npm:^5.22.1, undici@npm:^5.27.2": - version: 5.27.2 - resolution: "undici@npm:5.27.2" + version: 5.28.0 + resolution: "undici@npm:5.28.0" dependencies: "@fastify/busboy": "npm:^2.0.0" - checksum: 2bf96b102fb84568fb235bdf6e1e352e5d2bf99566b243cd1b13b41578bf9dd5c7c3d3d82192b20a3fec61fe7a528f9d80cd5b4555ce65405c06c69b023013de + checksum: 70afe17996fbb84a4febbda78b30ce627fc6db585afe0c5191426d277ff4162f62ae36ddbc252b8aaba5cc1fd4e09bc6db8a919ff59adb10008fb3882492a171 languageName: node linkType: hard @@ -35812,8 +35824,8 @@ __metadata: linkType: hard "wrangler@npm:^3.15.0": - version: 3.17.0 - resolution: "wrangler@npm:3.17.0" + version: 3.17.1 + resolution: "wrangler@npm:3.17.1" dependencies: "@cloudflare/kv-asset-handler": "npm:^0.2.0" "@esbuild-plugins/node-globals-polyfill": "npm:^0.2.3" @@ -35836,7 +35848,7 @@ __metadata: bin: wrangler: bin/wrangler.js wrangler2: bin/wrangler.js - checksum: 62139687f1b7887158336a6c3caa37aac05305665252c5dd87e01fda7cfac92f8530986f0859dc4215411827f1961d8673d15bc6d6d182aa4258fdd070fbc0eb + checksum: 44ccfbaabe18e882d692791587966b372a0d38b7742c93a7d99242cd25287a675f452c8a3a21bbb6bea8294d9eaf13e9991a7cc2533608bf95dca744cacfa156 languageName: node linkType: hard @@ -36066,7 +36078,7 @@ __metadata: version: 0.0.0-use.local resolution: "y-provider@workspace:packages/common/y-provider" dependencies: - "@blocksuite/store": "npm:0.0.0-20231122113751-6bf81eb3-nightly" + "@blocksuite/store": "npm:0.0.0-20231124123613-7c06e95d-nightly" vite: "npm:^4.4.11" vite-plugin-dts: "npm:3.6.0" vitest: "npm:0.34.6" From 2deceb6e8506feee6dae340c9f65ef61537cece7 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Mon, 27 Nov 2023 06:39:41 +0000 Subject: [PATCH 05/11] test(core): simple recovery ui e2e (#5059) --- tests/affine-cloud/e2e/page-history.spec.ts | 146 ++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 tests/affine-cloud/e2e/page-history.spec.ts diff --git a/tests/affine-cloud/e2e/page-history.spec.ts b/tests/affine-cloud/e2e/page-history.spec.ts new file mode 100644 index 0000000000..14ed1a7734 --- /dev/null +++ b/tests/affine-cloud/e2e/page-history.spec.ts @@ -0,0 +1,146 @@ +import { test } from '@affine-test/kit/playwright'; +import { + createRandomUser, + deleteUser, + enableCloudWorkspace, + loginUser, + runPrisma, +} from '@affine-test/kit/utils/cloud'; +import { + getBlockSuiteEditorTitle, + waitForEditorLoad, +} from '@affine-test/kit/utils/page-logic'; +import { createLocalWorkspace } from '@affine-test/kit/utils/workspace'; +import { expect, type Page } from '@playwright/test'; + +let user: { + id: string; + name: string; + email: string; + password: string; +}; + +test.beforeEach(async ({ page }) => { + user = await createRandomUser(); + await loginUser(page, user.email); +}); + +test.afterEach(async () => { + // if you want to keep the user in the database for debugging, + // comment this line + await deleteUser(user.email); +}); + +test('newly created page shows empty history', async ({ page }) => { + await page.reload(); + await waitForEditorLoad(page); + await createLocalWorkspace( + { + name: 'test', + }, + page + ); + await enableCloudWorkspace(page); + + // click the history button + await page.getByTestId('header-dropDownButton').click(); + await page.getByTestId('editor-option-menu-history').click(); + + const modal = page.getByTestId('page-history-modal'); + + // expect history modal shown up + await expect(modal).toBeVisible(); + + await expect(page.getByTestId('empty-history-prompt')).toBeVisible(); +}); + +const pushCurrentPageUpdates = async (page: Page) => { + const [workspaceId, guid, updates, state] = await page.evaluate(() => { + // @ts-expect-error + const Y = window.currentWorkspace.blockSuiteWorkspace.constructor.Y; + // @ts-expect-error + const spaceDoc = window.currentEditor.page.spaceDoc; + // @ts-expect-error + const workspaceId: string = window.currentWorkspace.id; + const updates: Uint8Array = Y.encodeStateAsUpdate(spaceDoc); + const state: Uint8Array = Y.encodeStateVector(spaceDoc); + + return [workspaceId, spaceDoc.guid, [...updates], [...state]] as const; + }); + + const toBuffer = (arr: readonly number[]) => Buffer.from(arr); + + await runPrisma(async client => { + await client.snapshotHistory.create({ + data: { + workspaceId: workspaceId, + id: guid, + blob: toBuffer(updates), + state: toBuffer(state), + timestamp: new Date(Date.now() - 10000), + expiredAt: new Date(Date.now() + 100000), + }, + }); + }); +}; + +test('can restore page to a history version', async ({ page }) => { + await page.reload(); + await waitForEditorLoad(page); + await createLocalWorkspace( + { + name: 'test', + }, + page + ); + await enableCloudWorkspace(page); + + await pushCurrentPageUpdates(page); + + const title = getBlockSuiteEditorTitle(page); + await title.pressSequentially('TEST TITLE', { + delay: 50, + }); + + // write something and push to history + await pushCurrentPageUpdates(page); + + await title.fill('New Title'); + + // click the history button + await page.getByTestId('header-dropDownButton').click(); + await page.getByTestId('editor-option-menu-history').click(); + + const modal = page.getByTestId('page-history-modal'); + + // expect history modal shown up + await expect(modal).toBeVisible(); + + // expect history list to have 2 items + await expect(modal.getByTestId('version-history-item')).toHaveCount(2); + + // check the first item in the preview should have title 'TEST TITLE' + await expect(modal.locator('[data-block-is-title]')).toHaveText('TEST TITLE'); + + // click restore + await modal + .getByRole('button', { + name: 'Restore current version', + }) + .click(); + + const confirm = page.getByTestId('confirm-restore-history-modal'); + + // expect confirm dialog to show up + await expect(confirm).toBeVisible(); + + // click restore + await confirm + .getByRole('button', { + name: 'Restore', + }) + .click(); + + // title should be restored to 'TEST TITLE' + await expect(title).toContainText('TEST TITLE'); +}); From 8cc9a0b21b5d8b4cefcadaf17ebf144d94e7b7e8 Mon Sep 17 00:00:00 2001 From: liuyi Date: Mon, 27 Nov 2023 07:06:30 +0000 Subject: [PATCH 06/11] feat(server): add soft deleted flag to optimized blob table (#5058) requires https://github.com/toeverything/OctoBase/pull/561 --- Cargo.lock | 10 +++++----- .../migration.sql | 2 ++ packages/backend/server/schema.prisma | 14 ++++++++------ packages/backend/storage/Cargo.toml | 6 +++--- 4 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 packages/backend/server/migrations/20231124091123_soft_delete_opt_blobs/migration.sql diff --git a/Cargo.lock b/Cargo.lock index 4f03beba90..3a340d7113 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1112,7 +1112,7 @@ dependencies = [ [[package]] name = "jwst-codec" version = "0.1.0" -source = "git+https://github.com/toeverything/OctoBase.git?rev=aad9e5b#aad9e5b7e9d6f479e6cf7555f5845bbbaaadbc66" +source = "git+https://github.com/toeverything/OctoBase.git?rev=49a6b7a#49a6b7af25ce1fe54e8383e10980e9536821d286" dependencies = [ "arbitrary", "bitvec", @@ -1133,7 +1133,7 @@ dependencies = [ [[package]] name = "jwst-core" version = "0.1.0" -source = "git+https://github.com/toeverything/OctoBase.git?rev=aad9e5b#aad9e5b7e9d6f479e6cf7555f5845bbbaaadbc66" +source = "git+https://github.com/toeverything/OctoBase.git?rev=49a6b7a#49a6b7af25ce1fe54e8383e10980e9536821d286" dependencies = [ "async-trait", "base64", @@ -1151,7 +1151,7 @@ dependencies = [ [[package]] name = "jwst-logger" version = "0.1.0" -source = "git+https://github.com/toeverything/OctoBase.git?rev=aad9e5b#aad9e5b7e9d6f479e6cf7555f5845bbbaaadbc66" +source = "git+https://github.com/toeverything/OctoBase.git?rev=49a6b7a#49a6b7af25ce1fe54e8383e10980e9536821d286" dependencies = [ "chrono", "nu-ansi-term 0.49.0", @@ -1164,7 +1164,7 @@ dependencies = [ [[package]] name = "jwst-storage" version = "0.1.0" -source = "git+https://github.com/toeverything/OctoBase.git?rev=aad9e5b#aad9e5b7e9d6f479e6cf7555f5845bbbaaadbc66" +source = "git+https://github.com/toeverything/OctoBase.git?rev=49a6b7a#49a6b7af25ce1fe54e8383e10980e9536821d286" dependencies = [ "anyhow", "async-trait", @@ -1189,7 +1189,7 @@ dependencies = [ [[package]] name = "jwst-storage-migration" version = "0.1.0" -source = "git+https://github.com/toeverything/OctoBase.git?rev=aad9e5b#aad9e5b7e9d6f479e6cf7555f5845bbbaaadbc66" +source = "git+https://github.com/toeverything/OctoBase.git?rev=49a6b7a#49a6b7af25ce1fe54e8383e10980e9536821d286" dependencies = [ "sea-orm-migration", "tokio", diff --git a/packages/backend/server/migrations/20231124091123_soft_delete_opt_blobs/migration.sql b/packages/backend/server/migrations/20231124091123_soft_delete_opt_blobs/migration.sql new file mode 100644 index 0000000000..6e107ce072 --- /dev/null +++ b/packages/backend/server/migrations/20231124091123_soft_delete_opt_blobs/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "optimized_blobs" ADD COLUMN "deleted_at" TIMESTAMPTZ(6); diff --git a/packages/backend/server/schema.prisma b/packages/backend/server/schema.prisma index a35a4187d2..640ad71c4a 100644 --- a/packages/backend/server/schema.prisma +++ b/packages/backend/server/schema.prisma @@ -178,13 +178,15 @@ model Blob { } model OptimizedBlob { - id Int @id @default(autoincrement()) @db.Integer - hash String @db.VarChar - workspaceId String @map("workspace_id") @db.VarChar - params String @db.VarChar - blob Bytes @db.ByteA + id Int @id @default(autoincrement()) @db.Integer + hash String @db.VarChar + workspaceId String @map("workspace_id") @db.VarChar + params String @db.VarChar + blob Bytes @db.ByteA length BigInt - createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6) + createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6) + // not for keeping, but for snapshot history + deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6) @@unique([workspaceId, hash, params]) @@map("optimized_blobs") diff --git a/packages/backend/storage/Cargo.toml b/packages/backend/storage/Cargo.toml index 7ccff97bdd..b1374cac9f 100644 --- a/packages/backend/storage/Cargo.toml +++ b/packages/backend/storage/Cargo.toml @@ -8,9 +8,9 @@ crate-type = ["cdylib"] [dependencies] chrono = "0.4" -jwst-codec = { git = "https://github.com/toeverything/OctoBase.git", rev = "aad9e5b" } -jwst-core = { git = "https://github.com/toeverything/OctoBase.git", rev = "aad9e5b" } -jwst-storage = { git = "https://github.com/toeverything/OctoBase.git", rev = "aad9e5b" } +jwst-codec = { git = "https://github.com/toeverything/OctoBase.git", rev = "49a6b7a" } +jwst-core = { git = "https://github.com/toeverything/OctoBase.git", rev = "49a6b7a" } +jwst-storage = { git = "https://github.com/toeverything/OctoBase.git", rev = "49a6b7a" } napi = { version = "2", default-features = false, features = [ "napi5", "async", From 30ec08cadfb3f94508e5eb3ea1154f9efd2acaec Mon Sep 17 00:00:00 2001 From: LongYinan Date: Mon, 27 Nov 2023 07:24:07 +0000 Subject: [PATCH 07/11] chore: bump the all-cargo-dependencies group with 5 updates (#5068) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [//]: # (dependabot-start) ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- [//]: # (dependabot-end) Bumps the all-cargo-dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | [napi](https://github.com/napi-rs/napi-rs) | `2.14.0` | `2.14.1` | | [napi-derive](https://github.com/napi-rs/napi-rs) | `2.14.1` | `2.14.2` | | [serde](https://github.com/serde-rs/serde) | `1.0.192` | `1.0.193` | | [sqlx](https://github.com/launchbadge/sqlx) | `0.7.2` | `0.7.3` | | [uuid](https://github.com/uuid-rs/uuid) | `1.6.0` | `1.6.1` | Updates `napi` from 2.14.0 to 2.14.1
Release notes

Sourced from napi's releases.

@​napi-rs/cli@​2.14.1

What's Changed

New Contributors

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.10.4...@​napi-rs/cli@​2.14.1

napi-derive@2.14.1

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-sys@2.3.0...napi-derive@2.14.1

napi@2.14.1

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi@2.14.0...napi@2.14.1

Commits
  • 6a4f4f1 chore(release): publish
  • e4ac44e Release independent packages
  • 8a9c42a fix(napi): compile error for wasm32-unknown-unknown target
  • 7dced93 fix(napi): cargo doc build
  • 751312c test: add test file name into error message (#1821)
  • 7c3f8b5 fix(napi-derive): compile warning (#1820)
  • 8c911b5 chore: upgrade emnapi dependencies (#1817)
  • 76dcf83 chore(deps): update dependency emnapi to v0.44.0 (#1805)
  • 6df0ca1 chore: 🤖 align wasi template to nodejs demo (#1814)
  • c321071 chore(deps): update dependency @​emnapi/runtime to v0.44.0 (#1804)
  • Additional commits viewable in compare view

Updates `napi-derive` from 2.14.1 to 2.14.2
Release notes

Sourced from napi-derive's releases.

napi-derive@2.14.2

What's Changed

Full Changelog: https://github.com/napi-rs/napi-rs/compare/napi-derive@2.14.1...napi-derive@2.14.2

Commits
  • 6a4f4f1 chore(release): publish
  • e4ac44e Release independent packages
  • 8a9c42a fix(napi): compile error for wasm32-unknown-unknown target
  • 7dced93 fix(napi): cargo doc build
  • 751312c test: add test file name into error message (#1821)
  • 7c3f8b5 fix(napi-derive): compile warning (#1820)
  • 8c911b5 chore: upgrade emnapi dependencies (#1817)
  • 76dcf83 chore(deps): update dependency emnapi to v0.44.0 (#1805)
  • 6df0ca1 chore: 🤖 align wasi template to nodejs demo (#1814)
  • c321071 chore(deps): update dependency @​emnapi/runtime to v0.44.0 (#1804)
  • Additional commits viewable in compare view

Updates `serde` from 1.0.192 to 1.0.193
Release notes

Sourced from serde's releases.

v1.0.193

Commits
  • 44613c7 Release 1.0.193
  • c706281 Merge pull request #2655 from dtolnay/rangestartend
  • 65d75b8 Add RangeFrom and RangeTo tests
  • 332b0cb Merge pull request #2654 from dtolnay/rangestartend
  • 8c4af41 Fix more RangeFrom / RangeEnd mixups
  • 24a78f0 Merge pull request #2653 from emilbonnek/fix/range-to-from-de-mixup
  • c91c334 Fix Range{From,To} deserialize mixup
  • 2083f43 Update ui test suite to nightly-2023-11-19
  • See full diff in compare view

Updates `sqlx` from 0.7.2 to 0.7.3
Changelog

Sourced from sqlx's changelog.

0.7.3 - 2023-11-22

38 pull requests were merged this release cycle.

Added

Changed

Fixed

... (truncated)

Commits

Updates `uuid` from 1.6.0 to 1.6.1
Release notes

Sourced from uuid's releases.

1.6.1

What's Changed

Full Changelog: https://github.com/uuid-rs/uuid/compare/1.6.0...1.6.1

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- Cargo.lock | 134 ++++++++++++++++++++-------- packages/frontend/native/Cargo.toml | 4 +- 2 files changed, 98 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a340d7113..6e263c1c4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,14 +83,15 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -240,6 +241,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-write-file" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c232177ba50b16fe7a4588495bd474a62a9e45a8e4ca6fd7d0b7ac29d164631e" +dependencies = [ + "nix", + "rand", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -941,7 +952,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", ] [[package]] @@ -950,7 +961,7 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", "allocator-api2", ] @@ -1257,9 +1268,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libsqlite3-sys" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" dependencies = [ "cc", "pkg-config", @@ -1337,6 +1348,15 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1375,9 +1395,9 @@ dependencies = [ [[package]] name = "napi" -version = "2.14.0" +version = "2.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d90182620f32fe34b6ac9b52cba898af26e94c7f5abc01eb4094c417ae2e6c" +checksum = "1133249c46e92da921bafc8aba4912bf84d6c475f7625183772ed2d0844dc3a7" dependencies = [ "anyhow", "bitflags 2.4.1", @@ -1399,9 +1419,9 @@ checksum = "d4b4532cf86bfef556348ac65e561e3123879f0e7566cca6d43a6ff5326f13df" [[package]] name = "napi-derive" -version = "2.14.1" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3619fa472d23cd5af94d63a2bae454a77a8863251f40230fbf59ce20eafa8a86" +checksum = "a0cca5738c6e81eb5ffd2c8ff2b4f05ece9c4c60c7e2b36cec6524492cf7f330" dependencies = [ "cfg-if", "convert_case", @@ -1413,9 +1433,9 @@ dependencies = [ [[package]] name = "napi-derive-backend" -version = "1.0.54" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd3ea4b54020c73d591a49cd192f6334c5f37f71a63ead54dbc851fa991ef00" +checksum = "35960e5f33228192a9b661447d0dfe8f5a3790ff5b4058c4d67680ded4f65b91" dependencies = [ "convert_case", "once_cell", @@ -1435,6 +1455,19 @@ dependencies = [ "libloading", ] +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", + "pin-utils", +] + [[package]] name = "no-std-compat" version = "0.4.1" @@ -2292,18 +2325,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -2450,9 +2483,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e50c216e3624ec8e7ecd14c6a6a6370aad6ee5d8cfc3ab30b5162eeeef2ed33" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" dependencies = [ "sqlx-core", "sqlx-macros", @@ -2463,11 +2496,11 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", "atoi", "bigdecimal", "byteorder", @@ -2511,9 +2544,9 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a793bb3ba331ec8359c1853bd39eed32cdd7baaf22c35ccf5c92a7e8d1189ec" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" dependencies = [ "proc-macro2", "quote", @@ -2524,10 +2557,11 @@ dependencies = [ [[package]] name = "sqlx-macros-core" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4ee1e104e00dedb6aa5ffdd1343107b0a4702e862a84320ee7cc74782d96fc" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" dependencies = [ + "atomic-write-file", "dotenvy", "either", "heck", @@ -2550,9 +2584,9 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" +checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" dependencies = [ "atoi", "base64", @@ -2597,9 +2631,9 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" dependencies = [ "atoi", "base64", @@ -2642,9 +2676,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f" +checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" dependencies = [ "atoi", "chrono", @@ -2662,6 +2696,7 @@ dependencies = [ "time", "tracing", "url", + "urlencoding", "uuid", ] @@ -3024,6 +3059,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8parse" version = "0.2.1" @@ -3032,9 +3073,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58fe91d841bc04822c9801002db4ea904b9e4b8e6bbad25127b46eff8dc516b" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "getrandom", "rand", @@ -3141,12 +3182,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.24.0" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" -dependencies = [ - "rustls-webpki", -] +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "whoami" @@ -3278,6 +3316,26 @@ dependencies = [ "tap", ] +[[package]] +name = "zerocopy" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/packages/frontend/native/Cargo.toml b/packages/frontend/native/Cargo.toml index 443fdd3f70..59973bf6da 100644 --- a/packages/frontend/native/Cargo.toml +++ b/packages/frontend/native/Cargo.toml @@ -25,7 +25,7 @@ rand = "0.8" serde = "1" serde_json = "1" sha3 = "0.10" -sqlx = { version = "0.7.2", default-features = false, features = [ +sqlx = { version = "0.7.3", default-features = false, features = [ "sqlite", "migrate", "runtime-tokio", @@ -44,7 +44,7 @@ uuid = { version = "1", default-features = false, features = [ affine_schema = { path = "./schema" } dotenv = "0.15" napi-build = "2" -sqlx = { version = "0.7.2", default-features = false, features = [ +sqlx = { version = "0.7.3", default-features = false, features = [ "sqlite", "runtime-tokio", "tls-rustls", From 9cdfeba9b4bbaee10813fe8105faff9334356226 Mon Sep 17 00:00:00 2001 From: EYHN Date: Mon, 27 Nov 2023 08:27:34 +0000 Subject: [PATCH 08/11] docs: issue triaging document (#5071) I would like to sort out our process for handling github issues. When we receive a issue, we should first triage it. This PR contains the document about issue triaging. reference: [YouTrack issue states used in .NET tools team and their description](https://rider-support.jetbrains.com/hc/en-us/articles/360021572199-YouTrack-issue-states-used-in-NET-tools-team-and-their-description) [vscode Issues Triaging](https://github.com/microsoft/vscode/wiki/Issues-Triaging) --- docs/issue-triaging.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 docs/issue-triaging.md diff --git a/docs/issue-triaging.md b/docs/issue-triaging.md new file mode 100644 index 0000000000..04283de3a5 --- /dev/null +++ b/docs/issue-triaging.md @@ -0,0 +1,28 @@ +# Issues Triaging + +When we receive your issue, we will first triaging it. Triaging an issue usually takes around one business day but may take longer. Goal of triaging is to provide you with a clear understanding of what will happen to your issue. For example, after your feature request was triaged you know whether we plan to tackle the issue or whether we'll wait to hear what the broader community thinks about this request. + +Here are issue states and their descriptions: + +| State | Description | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Untriaged | The team has not yet reviewed the issue. We usually do it within one business day. | +| As designed | The behavior described in the issue is intentional. If you find it seriously disruptive or if we’ve misunderstood you, please let us know in the issue’s comments section. | +| Blocked | We can’t work on this issue until another one (linked) is resolved. | +| Can’t Reproduce | We have been unable to reproduce the issue on our side. It could be flaky or fixed already, or we may not have had all the details we needed. If you’re still experiencing the issue and have any further details, please share them. | +| Duplicate | The issue is the same (or has the same cause) as another one (linked). | +| Fixed | If the issue was a bug, it’s been fixed; if it was a missing feature, it’s been implemented. | +| Fixed In Branch | If the issue was a bug, it’s been fixed; if it was a missing feature, it’s been implemented; the changes are now in a separate branch and haven’t been merged into the default branch yet. | +| In Progress | We’re currently working on the issue. | +| Incomplete | Unfortunately we don’t have enough information to proceed. If you’re willing to share any further details about the issue, please do so in the comments. | +| Obsolete | The part of the product that was causing this issue has been removed or significantly reworked since it was created. | +| Upvoting | We are currently evaluating demand for the issue and checking whether it requires complicated or risky changes. Please leave a vote or comment if you think it should be prioritized. | +| Open | We want to implement the fix or feature in the near future. We can’t promise it will appear in the next public release, but it’s on our short list. | +| Shelved | We have reviewed the issue and decided that, even though it has merit, we cannot currently include it in our near-term plan. | +| Third Party Problem | The issue is caused by a third party. We've done our best to inform them about it. | +| To be Discussed | We need some time to discuss the issue. | +| To Reproduce | We will try to find the steps needed to reproduce the issue on our side. | +| Under Investigation | We’ve triaged the issue, but now we need to investigate it more thoroughly. This may require processing additional information like logs or dumps. | +| Waiting for Info | We’ve requested additional information from the person who created the issue and are waiting for them to get back to us. | +| Declined | We’ve reviewed the suggestion and, while we appreciate its value, we unfortunately do not have the resources to implement it. | +| Answered | The issue actually turned out to be a question or a misunderstanding, and it has been answered or resolved. | From 8841dc3c4eecd4d4a42a22d22ad98f84fbd3cf39 Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Mon, 27 Nov 2023 08:45:33 +0000 Subject: [PATCH 09/11] fix(electron): electron dev startup on win (#5031) --- packages/frontend/electron/scripts/dev.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/frontend/electron/scripts/dev.ts b/packages/frontend/electron/scripts/dev.ts index 03796db9e7..fa22326a49 100644 --- a/packages/frontend/electron/scripts/dev.ts +++ b/packages/frontend/electron/scripts/dev.ts @@ -1,10 +1,11 @@ import { spawn } from 'node:child_process'; +import { resolve } from 'node:path'; import type { ChildProcessWithoutNullStreams } from 'child_process'; import type { BuildContext } from 'esbuild'; import * as esbuild from 'esbuild'; -import { config, electronDir } from './common'; +import { config, electronDir, rootDir } from './common'; // this means we don't spawn electron windows, mainly for testing const watchMode = process.argv.includes('--watch'); @@ -29,7 +30,10 @@ function spawnOrReloadElectron() { spawnProcess = null; } - spawnProcess = spawn('electron', ['.'], { + const ext = process.platform === 'win32' ? '.cmd' : ''; + const exe = resolve(rootDir, 'node_modules', '.bin', `electron${ext}`); + + spawnProcess = spawn(exe, ['.'], { cwd: electronDir, env: process.env, }); From 3891f23dfaf78e3acf5e73f10ad9ced73f4f61bf Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Mon, 27 Nov 2023 09:56:25 +0000 Subject: [PATCH 10/11] fix(component): rework tags list collapsing (#5072) Before: ![CleanShot 2023-11-27 at 16.39.55@2x.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/2ac2b8e3-6c30-41f7-a9b2-7a9c81b250fa.png) After: ![CleanShot 2023-11-27 at 16.38.50@2x.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/12eac806-e641-45be-9215-d166f8733db9.png) --- .../src/components/page-list/page-tags.css.ts | 23 ++++-- .../src/components/page-list/page-tags.tsx | 72 +++++-------------- 2 files changed, 35 insertions(+), 60 deletions(-) diff --git a/packages/frontend/component/src/components/page-list/page-tags.css.ts b/packages/frontend/component/src/components/page-list/page-tags.css.ts index 543c655216..fbf535da09 100644 --- a/packages/frontend/component/src/components/page-list/page-tags.css.ts +++ b/packages/frontend/component/src/components/page-list/page-tags.css.ts @@ -1,4 +1,6 @@ -import { style } from '@vanilla-extract/css'; +import { createVar, style } from '@vanilla-extract/css'; + +export const hoverMaxWidth = createVar(); export const root = style({ position: 'relative', @@ -15,7 +17,8 @@ export const tagsContainer = style({ export const tagsScrollContainer = style([ tagsContainer, { - overflow: 'auto', + overflowX: 'hidden', + position: 'relative', height: '100%', gap: '8px', }, @@ -41,7 +44,7 @@ export const innerContainer = style({ transition: 'all 0.2s 0.3s ease-in-out', selectors: { [`${root}:hover &`]: { - maxWidth: 'var(--hover-max-width)', + maxWidth: hoverMaxWidth, }, }, }); @@ -66,6 +69,16 @@ export const innerBackdrop = style({ export const tag = style({ height: '20px', + display: 'flex', + minWidth: 0, + alignItems: 'center', + justifyContent: 'space-between', + ':last-child': { + minWidth: 'max-content', + }, +}); + +export const tagInnerWrapper = style({ display: 'flex', alignItems: 'center', justifyContent: 'space-between', @@ -74,7 +87,7 @@ export const tag = style({ }); export const tagSticky = style([ - tag, + tagInnerWrapper, { fontSize: 'var(--affine-font-xs)', borderRadius: '10px', @@ -82,10 +95,8 @@ export const tagSticky = style([ border: '1px solid var(--affine-border-color)', background: 'var(--affine-background-primary-color)', maxWidth: '128px', - position: 'sticky', textOverflow: 'ellipsis', whiteSpace: 'nowrap', - left: 0, }, ]); diff --git a/packages/frontend/component/src/components/page-list/page-tags.tsx b/packages/frontend/component/src/components/page-list/page-tags.tsx index 8650979983..3fd43ea9df 100644 --- a/packages/frontend/component/src/components/page-list/page-tags.tsx +++ b/packages/frontend/component/src/components/page-list/page-tags.tsx @@ -1,8 +1,9 @@ import type { Tag } from '@affine/env/filter'; import { MoreHorizontalIcon } from '@blocksuite/icons'; import { Menu } from '@toeverything/components/menu'; +import { assignInlineVars } from '@vanilla-extract/dynamic'; import clsx from 'clsx'; -import { useEffect, useMemo, useRef } from 'react'; +import { useMemo } from 'react'; import * as styles from './page-tags.css'; import { stopPropagation } from './utils'; @@ -42,18 +43,22 @@ const TagItem = ({ tag, idx, mode, style }: TagItemProps) => { return (
-
{tag.value}
+ className={mode === 'sticky' ? styles.tagSticky : styles.tagListItem} + > +
+
{tag.value}
+
); }; @@ -69,26 +74,6 @@ export const PageTags = ({ ? widthOnHover : `${widthOnHover}px` : 'auto'; - const tagsContainerRef = useRef(null); - - useEffect(() => { - if (tagsContainerRef.current) { - const tagsContainer = tagsContainerRef.current; - const listener = () => { - // on mouseleave, reset scroll position to the hoverExpandDirection - tagsContainer.scrollTo({ - left: hoverExpandDirection === 'left' ? Number.MAX_SAFE_INTEGER : 0, - behavior: 'smooth', - }); - }; - listener(); - tagsContainerRef.current.addEventListener('mouseleave', listener); - return () => { - tagsContainer.removeEventListener('mouseleave', listener); - }; - } - return; - }, [hoverExpandDirection]); const tagsInPopover = useMemo(() => { const lastTags = tags.slice(maxItems); @@ -107,36 +92,17 @@ export const PageTags = ({ // sort tags by length nTags.sort((a, b) => a.value.length - b.value.length); - const tagRightCharLength = nTags.reduceRight( - (acc, tag) => { - const curr = acc[0] + Math.min(tag.value.length, 10); - return [curr, ...acc]; - }, - [0] - ); - - tagRightCharLength.shift(); - return nTags.map((tag, idx) => ( - + )); }, [maxItems, tags]); return (
-
- {tagsNormal} -
+
{tagsNormal}
{maxItems && tags.length > maxItems ? ( Date: Tue, 28 Nov 2023 05:54:42 +0000 Subject: [PATCH 11/11] fix(server): wrong OTEL config (#5084) --- packages/backend/server/src/metrics/opentelemetry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/server/src/metrics/opentelemetry.ts b/packages/backend/server/src/metrics/opentelemetry.ts index 77c6d55b3c..cd5fcfa358 100644 --- a/packages/backend/server/src/metrics/opentelemetry.ts +++ b/packages/backend/server/src/metrics/opentelemetry.ts @@ -66,7 +66,7 @@ class GCloudOpentelemetryFactor extends OpentelemetryFactor { override getMetricReader(): MetricReader { return new PeriodicExportingMetricReader({ exportIntervalMillis: 30000, - exportTimeoutMillis: 60000, + exportTimeoutMillis: 10000, exporter: new MetricExporter(), }); }