refactor(editor): remove assertExists (#10615)

This commit is contained in:
Saul-Mirone
2025-03-05 00:13:08 +00:00
parent a6692f70aa
commit b8ecfbdae6
106 changed files with 863 additions and 517 deletions

View File

@@ -3,7 +3,6 @@ import {
AIStarIconWithAnimation,
createLitPortal,
} from '@blocksuite/affine/blocks';
import { assertExists } from '@blocksuite/affine/global/utils';
import { flip, offset } from '@floating-ui/dom';
import { html, type TemplateResult } from 'lit';
@@ -169,7 +168,7 @@ function updateAIPanelConfig<T extends keyof BlockSuitePresets.AIActions>(
trackerOptions?: BlockSuitePresets.TrackerOptions
) {
const { config, host } = aiPanel;
assertExists(config);
if (!config) return;
config.generateAnswer = actionToGenerateAnswer(
host,
id,
@@ -203,7 +202,7 @@ export function actionToHandler<T extends keyof BlockSuitePresets.AIActions>(
const { selectedBlocks: blocks } = getSelections(aiPanel.host);
if (!blocks || blocks.length === 0) return;
const block = blocks.at(-1);
assertExists(block);
if (!block) return;
aiPanel.toggle(block, '');
};
}

View File

@@ -14,7 +14,6 @@ import {
splitElements,
TextElementModel,
} from '@blocksuite/affine/blocks';
import { assertExists } from '@blocksuite/affine/global/utils';
import { Slice } from '@blocksuite/affine/store';
import type { TemplateResult } from 'lit';
@@ -319,7 +318,7 @@ function updateEdgelessAIPanelConfig<
) {
const host = aiPanel.host;
const { config } = aiPanel;
assertExists(config);
if (!config) return;
config.answerRenderer = actionToAnswerRenderer(id, host, ctx);
config.generateAnswer = actionToGeneration(
id,
@@ -414,7 +413,7 @@ export function actionToHandler<T extends keyof BlockSuitePresets.AIActions>(
referenceElement = getElementToolbar(host);
} else if (!isEmpty) {
const lastSelected = selectedElements.at(-1)?.id;
assertExists(lastSelected);
if (!lastSelected) return;
const noteAnchor = getSelectedNoteAnchor(host, lastSelected);
referenceElement = noteAnchor;
}

View File

@@ -23,7 +23,6 @@ import {
TelemetryProvider,
} from '@blocksuite/affine/blocks';
import { Bound } from '@blocksuite/affine/global/gfx';
import { assertExists } from '@blocksuite/affine/global/utils';
import { html, type TemplateResult } from 'lit';
import { styleMap } from 'lit/directives/style-map.js';
@@ -238,7 +237,7 @@ function createBlockAndInsert(
const doc = host.doc;
const edgelessCopilot = getEdgelessCopilotWidget(host);
doc.transact(() => {
assertExists(doc.root);
if (!doc.root) return;
let blockId = '';
const bounds = edgelessCopilot.determineInsertionBounds(
EDGELESS_TEXT_BLOCK_MIN_WIDTH,
@@ -280,8 +279,7 @@ function createBlockAndInsert(
const defaultHandler = (host: EditorHost) => {
const panel = getAIPanelWidget(host);
const selectedElements = getCopilotSelectedElems(host);
assertExists(panel.answer);
if (!panel.answer) return;
if (
selectedElements.length === 1 &&
selectedElements[0] instanceof EdgelessTextBlockModel

View File

@@ -9,7 +9,6 @@ import {
NoteDisplayMode,
} from '@blocksuite/affine/blocks';
import { Bound } from '@blocksuite/affine/global/gfx';
import { assertExists } from '@blocksuite/affine/global/utils';
import type { FrameworkProvider } from '@toeverything/infra';
import type { TemplateResult } from 'lit';
@@ -98,7 +97,7 @@ function createNewNote(host: EditorHost): AIItemConfig {
const panel = getAIPanelWidget(host);
const gfx = host.std.get(GfxControllerIdentifier);
doc.transact(() => {
assertExists(doc.root);
if (!doc.root || !panel.answer) return;
const noteBlockId = doc.addBlock(
'affine:note',
{
@@ -109,7 +108,6 @@ function createNewNote(host: EditorHost): AIItemConfig {
doc.root.id
);
assertExists(panel.answer);
insertFromMarkdown(host, panel.answer, doc, noteBlockId)
.then(() => {
gfx.selection.set({

View File

@@ -7,14 +7,12 @@ import {
AIStarIcon,
DocModeProvider,
} from '@blocksuite/affine/blocks';
import { assertExists } from '@blocksuite/affine/global/utils';
import { MoreHorizontalIcon } from '@blocksuite/icons/lit';
import { html } from 'lit';
import { pageAIGroups } from '../../_common/config';
import { handleInlineAskAIAction } from '../../actions/doc-handler';
import type { AIItemConfig } from '../../components/ai-item/types';
import { AIProvider } from '../../provider';
import {
AFFINE_AI_PANEL_WIDGET,
type AffineAIPanelWidget,
@@ -55,10 +53,9 @@ export function setupSlashMenuAIEntry(slashMenu: AffineSlashMenuWidget) {
});
const subMenuWrapper = (item: AIItemConfig): AffineSlashSubMenu => {
assertExists(item.subItem);
return {
...basicItemConfig(item),
subMenu: item.subItem.map<AffineSlashMenuActionItem>(
subMenu: (item.subItem ?? []).map<AffineSlashMenuActionItem>(
({ type, handler }) => ({
name: type,
action: ({ rootComponent }) => handler?.(rootComponent.host),
@@ -87,9 +84,6 @@ export function setupSlashMenuAIEntry(slashMenu: AffineSlashMenuWidget) {
AFFINE_AI_PANEL_WIDGET,
rootComponent.model.id
) as AffineAIPanelWidget;
assertExists(affineAIPanelWidget);
assertExists(AIProvider.actions.chat);
assertExists(affineAIPanelWidget.host);
handleInlineAskAIAction(affineAIPanelWidget.host);
},
});

View File

@@ -1,4 +1,3 @@
import { assertExists } from '@blocksuite/affine/global/utils';
import { partition } from 'lodash-es';
import { AIProvider } from './ai-provider';
@@ -146,7 +145,6 @@ export function textToText({
if (retry) {
const retrySessionId =
(await sessionId) ?? AIProvider.LAST_ACTION_SESSIONID;
assertExists(retrySessionId, 'retry sessionId is required');
_sessionId = retrySessionId;
_messageId = undefined;
} else {
@@ -220,7 +218,6 @@ export function textToText({
if (retry) {
const retrySessionId =
(await sessionId) ?? AIProvider.LAST_ACTION_SESSIONID;
assertExists(retrySessionId, 'retry sessionId is required');
_sessionId = retrySessionId;
_messageId = undefined;
} else {
@@ -275,7 +272,6 @@ export function toImage({
if (retry) {
const retrySessionId =
(await sessionId) ?? AIProvider.LAST_ACTION_SESSIONID;
assertExists(retrySessionId, 'retry sessionId is required');
_sessionId = retrySessionId;
_messageId = undefined;
} else {

View File

@@ -5,7 +5,6 @@ import {
type getCopilotHistoriesQuery,
type RequestOptions,
} from '@affine/graphql';
import { assertExists } from '@blocksuite/affine/global/utils';
import { z } from 'zod';
import { AIProvider } from './ai-provider';
@@ -234,7 +233,9 @@ export function setupAIProvider(
});
AIProvider.provide('expandMindmap', options => {
assertExists(options.input, 'expandMindmap action requires input');
if (!options.input) {
throw new Error('expandMindmap action requires input');
}
return textToText({
...options,
client,

View File

@@ -1,5 +1,4 @@
import type { EditorHost } from '@blocksuite/affine/block-std';
import { assertExists } from '@blocksuite/affine/global/utils';
import {
AFFINE_AI_PANEL_WIDGET,
@@ -8,9 +7,10 @@ import {
export const getAIPanelWidget = (host: EditorHost): AffineAIPanelWidget => {
const rootBlockId = host.doc.root?.id;
assertExists(rootBlockId);
if (!rootBlockId) {
throw new Error('rootBlockId is not found');
}
const aiPanel = host.view.getWidget(AFFINE_AI_PANEL_WIDGET, rootBlockId);
assertExists(aiPanel);
if (!(aiPanel instanceof AffineAIPanelWidget)) {
throw new Error('AI panel not found');
}

View File

@@ -3,7 +3,6 @@ import {
type EdgelessRootService,
SurfaceBlockComponent,
} from '@blocksuite/affine/blocks';
import { assertExists } from '@blocksuite/affine/global/utils';
export const getConnectorFromId = (
id: string,
@@ -68,7 +67,9 @@ export const findTree = (
};
};
const tree = run(rootId);
assertExists(tree);
if (!tree) {
throw new Error('tree is not found');
}
return tree;
};
export const findLeaf = (

View File

@@ -1,5 +1,4 @@
import { FetchUtils } from '@blocksuite/affine/blocks';
import { assertExists } from '@blocksuite/affine/global/utils';
export async function fetchImageToFile(
url: string,
@@ -26,14 +25,17 @@ function fetchImageFallback(
url: string,
filename: string
): Promise<File | void> {
return new Promise(resolve => {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
const c = document.createElement('canvas');
c.width = img.width;
c.height = img.height;
const ctx = c.getContext('2d');
assertExists(ctx);
if (!ctx) {
reject();
return;
}
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
ctx.drawImage(img, 0, 0);
@@ -51,7 +53,7 @@ function fetchImageFallback(
}
function convertToPng(blob: Blob): Promise<Blob | null> {
return new Promise(resolve => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener('load', _ => {
const img = new Image();
@@ -60,7 +62,10 @@ function convertToPng(blob: Blob): Promise<Blob | null> {
c.width = img.width;
c.height = img.height;
const ctx = c.getContext('2d');
assertExists(ctx);
if (!ctx) {
reject();
return;
}
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
ctx.drawImage(img, 0, 0);

View File

@@ -6,11 +6,12 @@ import {
TemplateMiddlewares,
} from '@blocksuite/affine/blocks';
import { Bound, getCommonBound } from '@blocksuite/affine/global/gfx';
import { assertExists } from '@blocksuite/affine/global/utils';
export function createTemplateJob(host: EditorHost) {
const surface = getSurfaceBlock(host.doc);
assertExists(surface);
if (!surface) {
throw new Error('surface is not found');
}
const middlewares: ((job: TemplateJob) => void)[] = [];
const layer = new LayerManager(host.doc, surface, {

View File

@@ -13,7 +13,6 @@ import {
stopPropagation,
ThemeProvider,
} from '@blocksuite/affine/blocks';
import { assertExists } from '@blocksuite/affine/global/utils';
import type { BaseSelection } from '@blocksuite/affine/store';
import {
autoPlacement,
@@ -176,10 +175,16 @@ export class AffineAIPanelWidget extends WidgetComponent {
generate = () => {
this.restoreSelection();
assertExists(this.config);
const text = this._inputText;
assertExists(text);
assertExists(this.config.generateAnswer);
if (!this.config) {
throw new Error('config is not found');
}
if (text === null || text === undefined) {
throw new Error('text is not found');
}
if (!this.config.generateAnswer) {
throw new Error('generateAnswer is not found');
}
this._resetAbortController();
@@ -193,7 +198,9 @@ export class AffineAIPanelWidget extends WidgetComponent {
const finish = (type: 'success' | 'error' | 'aborted', err?: AIError) => {
if (type === 'aborted') return;
assertExists(this.config);
if (!this.config) {
throw new Error('config is not found when finish');
}
if (type === 'error') {
this.state = 'error';
this.config.errorStateConfig.error = err;

View File

@@ -1,5 +1,4 @@
import { apis } from '@affine/electron-api';
import { assertExists } from '@blocksuite/affine/global/utils';
import type { AppConfigSchema } from '@toeverything/infra';
import { AppConfigStorage, defaultAppConfig } from '@toeverything/infra';
import type { Dispatch } from 'react';
@@ -12,12 +11,16 @@ class AppConfigProxy {
value: AppConfigSchema = defaultAppConfig;
async getSync(): Promise<AppConfigSchema> {
assertExists(apis);
if (!apis) {
throw new Error('electron apis is not found');
}
return (this.value = await apis.configStorage.get());
}
async setSync(): Promise<void> {
assertExists(apis);
if (!apis) {
throw new Error('electron apis is not found');
}
await apis.configStorage.set(this.value);
}

View File

@@ -11,7 +11,6 @@ import type {
VariableMap,
} from '@affine/env/filter';
import { getOrCreateI18n, I18nextProvider } from '@affine/i18n';
import { assertExists } from '@blocksuite/affine/global/utils';
import { render } from '@testing-library/react';
import type { ReactElement } from 'react';
import { useState } from 'react';
@@ -77,7 +76,9 @@ describe('match filter', () => {
describe('eval filter', () => {
test('before', async () => {
const before = filterMatcher.findData(v => v.name === 'before');
assertExists(before);
if (!before) {
throw new Error('before is not found');
}
const filter1 = filter(before, ref('Created'), [
new Date(2023, 5, 28).getTime(),
]);
@@ -96,7 +97,9 @@ describe('eval filter', () => {
});
test('after', async () => {
const after = filterMatcher.findData(v => v.name === 'after');
assertExists(after);
if (!after) {
throw new Error('after is not found');
}
const filter1 = filter(after, ref('Created'), [
new Date(2023, 5, 28).getTime(),
]);
@@ -115,7 +118,9 @@ describe('eval filter', () => {
});
test('is', async () => {
const is = filterMatcher.findData(v => v.name === 'is');
assertExists(is);
if (!is) {
throw new Error('is is not found');
}
const filter1 = filter(is, ref('Is Favourited'), [false]);
const filter2 = filter(is, ref('Is Favourited'), [true]);
const varMap = mockVariableMap({
@@ -130,7 +135,9 @@ describe('render filter', () => {
test('boolean condition value change', async () => {
const is = filterMatcher.match(tBoolean.create());
const i18n = getOrCreateI18n();
assertExists(is);
if (!is) {
throw new Error('is is not found');
}
const Wrapper = () => {
const [value, onChange] = useState(
filter(is, ref('Is Favourited'), [true])
@@ -169,7 +176,9 @@ describe('render filter', () => {
test('date condition function change', async () => {
const dateFunction = filterMatcher.match(tDate.create());
assertExists(dateFunction);
if (!dateFunction) {
throw new Error('dateFunction is not found');
}
const Wrapper = WrapperCreator(dateFunction);
const result = render(<Wrapper />);
const dom = await result.findByTestId('filter-name');
@@ -179,7 +188,9 @@ describe('render filter', () => {
});
test('date condition variable change', async () => {
const dateFunction = filterMatcher.match(tDate.create());
assertExists(dateFunction);
if (!dateFunction) {
throw new Error('dateFunction is not found');
}
const Wrapper = WrapperCreator(dateFunction);
const result = render(<Wrapper />);
const dom = await result.findByTestId('variable-name');

View File

@@ -4,7 +4,6 @@
import 'fake-indexeddb/auto';
import { StoreExtensions } from '@blocksuite/affine/blocks';
import { assertExists } from '@blocksuite/affine/global/utils';
import { type Store, Text } from '@blocksuite/affine/store';
import { TestWorkspace } from '@blocksuite/affine/store/test';
import { renderHook } from '@testing-library/react';
@@ -23,7 +22,6 @@ beforeEach(async () => {
const initPage = async (page: Store) => {
page.load();
expect(page).not.toBeNull();
assertExists(page);
const pageBlockId = page.addBlock('affine:page', {
title: new Text(''),
});

View File

@@ -2,7 +2,6 @@ import { shallowEqual } from '@affine/component';
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
import type { Tag } from '@affine/env/filter';
import { useI18n } from '@affine/i18n';
import { assertExists } from '@blocksuite/affine/global/utils';
import type { DocMeta, Workspace } from '@blocksuite/affine/store';
import { ToggleRightIcon, ViewLayersIcon } from '@blocksuite/icons/rc';
import * as Collapsible from '@radix-ui/react-collapsible';
@@ -301,7 +300,9 @@ function pageMetaToListItemProp(
): PageListItemProps {
const toggleSelection = props.onSelectedIdsChange
? () => {
assertExists(props.selectedIds);
if (!props.selectedIds) {
throw new Error('selectedIds is not found');
}
const prevSelected = props.selectedIds.includes(item.id);
const shouldAdd = !prevSelected;
const shouldRemove = prevSelected;
@@ -345,7 +346,9 @@ function collectionMetaToListItemProp(
): CollectionListItemProps {
const toggleSelection = props.onSelectedIdsChange
? () => {
assertExists(props.selectedIds);
if (!props.selectedIds) {
throw new Error('selectedIds is not found');
}
const prevSelected = props.selectedIds.includes(item.id);
const shouldAdd = !prevSelected;
const shouldRemove = prevSelected;
@@ -382,7 +385,9 @@ function tagMetaToListItemProp(
): TagListItemProps {
const toggleSelection = props.onSelectedIdsChange
? () => {
assertExists(props.selectedIds);
if (!props.selectedIds) {
throw new Error('selectedIds is not found');
}
const prevSelected = props.selectedIds.includes(item.id);
const shouldAdd = !prevSelected;
const shouldRemove = prevSelected;

View File

@@ -1,6 +1,5 @@
import { notify } from '@affine/component';
import { GraphQLError } from '@affine/graphql';
import { assertExists } from '@blocksuite/affine/global/utils';
import type { PropsWithChildren, ReactNode } from 'react';
import { useCallback } from 'react';
import type { SWRConfiguration } from 'swr';
@@ -12,7 +11,9 @@ const swrConfig: SWRConfiguration = {
useSWRNext => (key, fetcher, config) => {
const fetcherWrapper = useCallback(
async (...args: any[]) => {
assertExists(fetcher);
if (!fetcher) {
throw new Error('fetcher is not found');
}
const d = fetcher(...args);
if (d instanceof Promise) {
return d.catch(e => {

View File

@@ -8,7 +8,6 @@ import { GlobalContextService } from '@affine/core/modules/global-context';
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
import { WorkspaceService } from '@affine/core/modules/workspace';
import { useI18n } from '@affine/i18n';
import { assertExists } from '@blocksuite/affine/global/utils';
import { DeleteIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra';
import { useEffect } from 'react';
@@ -44,7 +43,6 @@ export const TrashPage = () => {
const isAdmin = useLiveData(permissionService.permission.isAdmin$);
const isOwner = useLiveData(permissionService.permission.isOwner$);
const docCollection = currentWorkspace.docCollection;
assertExists(docCollection);
const pageMetas = useBlockSuiteDocMeta(docCollection);
const filteredPageMetas = useFilteredPageMetas(pageMetas, {

View File

@@ -1,4 +1,3 @@
import { assertExists } from '@blocksuite/affine/global/utils';
import { useLiveData, useService } from '@toeverything/infra';
import { Fragment, useCallback, useEffect } from 'react';
@@ -9,10 +8,9 @@ import { OpenInAppPage } from './open-in-app-page';
* Web only guard to open the URL in desktop app for different conditions
*/
const WebOpenInAppGuard = ({ children }: { children: React.ReactNode }) => {
assertExists(
BUILD_CONFIG.isWeb,
'WebOpenInAppGuard should only be used in web'
);
if (BUILD_CONFIG.isWeb === undefined || BUILD_CONFIG.isWeb === null) {
throw new Error('WebOpenInAppGuard should only be used in web');
}
const service = useService(OpenInAppService);
const shouldOpenInApp = useLiveData(service.showOpenInAppPage$);