From 0b99692a4d8a434bbf9ef3254889c802183e5a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E7=86=B1?= Date: Thu, 21 May 2026 21:16:41 +0800 Subject: [PATCH] refactor(core): cleanup unused utilities (#6908) --- packages/core/src/common/function.ts | 6 +++ .../text-x/build-utils/text-x-utils.ts | 6 +-- packages/core/src/index.ts | 45 ++++++++++++++++--- packages/core/src/shared/text-diff.ts | 17 ------- packages/core/src/shared/timer.ts | 14 ++++++ packages/core/src/shared/tools.ts | 29 ------------ .../__tests__/drawing-commands.spec.ts | 17 +++---- .../docs-hyper-link-ui.integration.spec.ts | 11 ++--- .../docs-mention-ui.integration.spec.ts | 10 ++--- .../__tests__/break-line.command.spec.ts | 8 +--- .../__tests__/core-editing.command.spec.ts | 11 ++--- .../commands/__tests__/list.command.spec.ts | 14 +++--- .../commands/__tests__/misc.command.spec.ts | 23 +++++----- .../__tests__/set-heading.command.spec.ts | 10 ++--- .../doc-ime-input.controller.spec.ts | 13 +++--- .../services/clipboard/clipboard.service.ts | 4 +- .../services/clipboard/copy-content-cache.ts | 7 +-- .../src/__tests__/docs.integration.spec.ts | 11 ++--- packages/engine-render/src/engine.ts | 4 +- .../__tests__/find-replace.service.spec.ts | 5 ++- .../http/interceptors/merge-interceptor.ts | 2 +- .../rpc/__tests__/channel.service.spec.ts | 9 +--- .../rpc/__tests__/rpc.service.edge.spec.ts | 15 +++---- .../__tests__/dv-rerender.controller.spec.ts | 3 +- .../formula-input/ListFormulaInput.tsx | 6 +-- .../sheets-filter-panel.service.spec.ts | 6 +-- .../worker/generate-filter-values.service.ts | 14 ++++-- .../help-function/HelpFunction.tsx | 3 +- .../hooks/use-sheet-selection-change.ts | 23 ++++++++-- .../src/views/formula-editor/index.tsx | 12 +++-- .../search-function/SearchFunction.tsx | 3 +- ...ormula-cell-interceptor.controller.spec.ts | 5 +-- .../__tests__/render.controller.spec.ts | 3 +- .../controllers/numfmt.editor.controller.ts | 4 -- .../__tests__/copy-content-cache.spec.ts | 5 ++- .../services/clipboard/clipboard.service.ts | 35 ++++++++++++--- .../services/clipboard/copy-content-cache.ts | 7 +-- .../__tests__/thread-comment.model.spec.ts | 5 ++- .../watermark.render.controller.spec.ts | 12 ++--- 39 files changed, 214 insertions(+), 223 deletions(-) delete mode 100644 packages/core/src/shared/text-diff.ts diff --git a/packages/core/src/common/function.ts b/packages/core/src/common/function.ts index a8daa95497..1f7b6a2edd 100644 --- a/packages/core/src/common/function.ts +++ b/packages/core/src/common/function.ts @@ -14,6 +14,12 @@ * limitations under the License. */ +/** + * A no-op (no operation) function that does nothing. + * Use this as a default placeholder for callbacks or optional handlers. + */ +export function noop(): void {} + export function throttle any>(fn: T, wait: number = 16): T { let lastTime = 0; let timer: number | null = null; diff --git a/packages/core/src/docs/data-model/text-x/build-utils/text-x-utils.ts b/packages/core/src/docs/data-model/text-x/build-utils/text-x-utils.ts index 39c5f96fc1..5604a84003 100644 --- a/packages/core/src/docs/data-model/text-x/build-utils/text-x-utils.ts +++ b/packages/core/src/docs/data-model/text-x/build-utils/text-x-utils.ts @@ -21,8 +21,8 @@ import type { CustomRangeType, IDocumentBody, ITextRun } from '../../../../types import type { DocumentDataModel } from '../../document-data-model'; import type { TextXAction } from '../action-types'; import type { TextXSelection } from '../text-x'; +import fastDiff from 'fast-diff'; import { Tools, UpdateDocsAttributeType } from '../../../../shared'; -import { textDiff } from '../../../../shared/text-diff'; import { TextXActionType } from '../action-types'; import { TextX } from '../text-x'; import { getBodySlice, getTextRunSlice } from '../utils'; @@ -284,7 +284,7 @@ export const replaceSelectionTextX = (params: IReplaceSelectionTextXParams) => { if (!body) return false; const oldBody = selection.collapsed ? null : getBodySlice(body, selection.startOffset, selection.endOffset); - const diffs = textDiff(oldBody ? oldBody.dataStream : '', insertBody.dataStream); + const diffs = fastDiff(oldBody ? oldBody.dataStream : '', insertBody.dataStream); let cursor = 0; const actions = diffs.map(([type, text]) => { switch (type) { @@ -350,7 +350,7 @@ export const replaceSelectionTextRuns = (params: IReplaceSelectionTextRunsParams if (!body) return false; const oldBody = selection.collapsed ? null : getBodySlice(body, selection.startOffset, selection.endOffset); - const diffs = textDiff(oldBody ? oldBody.dataStream : '', insertBody.dataStream); + const diffs = fastDiff(oldBody ? oldBody.dataStream : '', insertBody.dataStream); let cursor = 0; const actions = diffs.map(([type, text]) => { switch (type) { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index bd82b2ca2d..f1812a7805 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -25,9 +25,22 @@ export * from './common/const'; export * from './common/di'; export { shallowEqual } from './common/equal'; export { CanceledError, CustomCommandExecutionError } from './common/error'; -export { throttle } from './common/function'; -export type { IAsyncInterceptor, ICellInterceptor, IComposeInterceptors, IInterceptor, InterceptorHandler } from './common/interceptor'; -export { AsyncInterceptorManager, composeInterceptors, createAsyncInterceptorKey, createInterceptorKey, InterceptorEffectEnum, InterceptorManager } from './common/interceptor'; +export { noop, throttle } from './common/function'; +export type { + IAsyncInterceptor, + ICellInterceptor, + IComposeInterceptors, + IInterceptor, + InterceptorHandler, +} from './common/interceptor'; +export { + AsyncInterceptorManager, + composeInterceptors, + createAsyncInterceptorKey, + createInterceptorKey, + InterceptorEffectEnum, + InterceptorManager, +} from './common/interceptor'; export { invertColorByHSL } from './common/invert-color/invert-hsl'; // invert color utils export { invertColorByMatrix } from './common/invert-color/invert-rgb'; @@ -47,7 +60,15 @@ export * from './docs/data-model'; export { JSON1, JSONX } from './docs/data-model/json-x/json-x'; export type { JSONXActions, JSONXPath } from './docs/data-model/json-x/json-x'; export { replaceInDocumentBody } from './docs/data-model/replacement'; -export { ParagraphStyleBuilder, ParagraphStyleValue, RichTextBuilder, RichTextValue, TextDecorationBuilder, TextStyleBuilder, TextStyleValue } from './docs/data-model/rich-text-builder'; +export { + ParagraphStyleBuilder, + ParagraphStyleValue, + RichTextBuilder, + RichTextValue, + TextDecorationBuilder, + TextStyleBuilder, + TextStyleValue, +} from './docs/data-model/rich-text-builder'; export { DEFAULT_DOCUMENT_SUB_COMPONENT_ID } from './docs/data-model/subdocument'; export { ActionIterator } from './docs/data-model/text-x/action-iterator'; export { @@ -119,7 +140,12 @@ export { PermissionService } from './services/permission/permission.service'; export { IPermissionService, PermissionStatus } from './services/permission/type'; export type { IPermissionParam } from './services/permission/type'; export type { IPermissionPoint } from './services/permission/type'; -export type { IPermissionTypes, RangePermissionPointConstructor, WorkbookPermissionPointConstructor, WorkSheetPermissionPointConstructor } from './services/permission/type'; +export type { + IPermissionTypes, + RangePermissionPointConstructor, + WorkbookPermissionPointConstructor, + WorkSheetPermissionPointConstructor, +} from './services/permission/type'; export { type DependencyOverride, mergeOverrideWithDependencies } from './services/plugin/plugin-override'; export type { PluginCtor } from './services/plugin/plugin.service'; export { DependentOn, Plugin, PluginService } from './services/plugin/plugin.service'; @@ -150,7 +176,6 @@ export { customNameCharacterCheck, nameCharacterCheck } from './shared/name'; export { type BBox, type IRTreeItem, RBush, RTree } from './shared/r-tree'; export { getIntersectRange } from './shared/range'; export { afterTime, bufferDebounceTime, convertObservableToBehaviorSubject, fromCallback, takeAfter } from './shared/rxjs'; -export { textDiff } from './shared/text-diff'; export { awaitTime, delayAnimationFrame } from './shared/timer'; export { isNodeEnv } from './shared/tools'; export * from './sheets/clone'; @@ -194,5 +219,11 @@ export { DataValidationStatus } from './types/enum/data-validation-status'; export { DataValidationType } from './types/enum/data-validation-type'; export * from './types/interfaces'; export type { ICellCustomRender, ICellRenderContext } from './types/interfaces/i-cell-custom-render'; -export type { IDataValidationRule, IDataValidationRuleBase, IDataValidationRuleInfo, IDataValidationRuleOptions, ISheetDataValidationRule } from './types/interfaces/i-data-validation'; +export type { + IDataValidationRule, + IDataValidationRuleBase, + IDataValidationRuleInfo, + IDataValidationRuleOptions, + ISheetDataValidationRule, +} from './types/interfaces/i-data-validation'; export { type IUniverConfig, Univer } from './univer'; diff --git a/packages/core/src/shared/text-diff.ts b/packages/core/src/shared/text-diff.ts deleted file mode 100644 index 8d218e38d7..0000000000 --- a/packages/core/src/shared/text-diff.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright 2023-present DreamNum Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default as textDiff } from 'fast-diff'; diff --git a/packages/core/src/shared/timer.ts b/packages/core/src/shared/timer.ts index 17f9aa5d5c..a767ca71ca 100644 --- a/packages/core/src/shared/timer.ts +++ b/packages/core/src/shared/timer.ts @@ -14,10 +14,24 @@ * limitations under the License. */ +/** + * Returns a Promise that resolves after the specified number of milliseconds. + * Use this to pause execution for a given duration. + * + * @param ms The number of milliseconds to wait before resolving. + * @returns A Promise that resolves after `ms` milliseconds. + */ export function awaitTime(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } +/** + * Returns a Promise that resolves after the specified number of animation frames. + * Use this to wait for the browser to complete one or more rendering cycles. + * + * @param frames The number of animation frames to wait before resolving. Defaults to `1`. + * @returns A Promise that resolves after `frames` animation frames. + */ export function delayAnimationFrame(frames: number = 1): Promise { return new Promise((resolve) => { let count = 0; diff --git a/packages/core/src/shared/tools.ts b/packages/core/src/shared/tools.ts index 7fceb42401..70ebb7d930 100644 --- a/packages/core/src/shared/tools.ts +++ b/packages/core/src/shared/tools.ts @@ -19,35 +19,6 @@ import type { Nullable } from './types'; import { customAlphabet, nanoid } from 'nanoid'; import { isLegalUrl, normalizeUrl, topLevelDomainSet } from '../common/url'; -const alphabets = [ - 'A', - 'B', - 'C', - 'D', - 'E', - 'F', - 'G', - 'H', - 'I', - 'J', - 'K', - 'L', - 'M', - 'N', - 'O', - 'P', - 'Q', - 'R', - 'S', - 'T', - 'U', - 'V', - 'W', - 'X', - 'Y', - 'Z', -]; - /** * Deep diff between two object * @param oneValue The first test value diff --git a/packages/docs-drawing-ui/src/commands/commands/__tests__/drawing-commands.spec.ts b/packages/docs-drawing-ui/src/commands/commands/__tests__/drawing-commands.spec.ts index 104fbfb700..371ddb05cd 100644 --- a/packages/docs-drawing-ui/src/commands/commands/__tests__/drawing-commands.spec.ts +++ b/packages/docs-drawing-ui/src/commands/commands/__tests__/drawing-commands.spec.ts @@ -16,6 +16,7 @@ import type { DocumentDataModel, ICommand, IDocumentData, Injector } from '@univerjs/core'; import { + awaitTime, Direction, ICommandService, IUniverInstanceService, @@ -37,10 +38,6 @@ import { MoveDocDrawingsCommand } from '../move-drawings.command'; import { RemoveDocDrawingCommand } from '../remove-doc-drawing.command'; import { UpdateDocDrawingDistanceCommand, UpdateDocDrawingWrapTextCommand, UpdateDrawingDocTransformCommand } from '../update-doc-drawing.command'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function createBaseDocData(): IDocumentData { return { id: 'test-doc', @@ -197,7 +194,7 @@ describe('docs drawing commands integration', () => { }, }], })).toBe(true); - await waitNextTick(); + await awaitTime(0); const doc = testBed.get(IUniverInstanceService) .getUnit('test-doc', UniverInstanceType.UNIVER_DOC)!; @@ -220,7 +217,7 @@ describe('docs drawing commands integration', () => { testBed.docDrawingService.focusDrawing([{ unitId: 'test-doc', subUnitId: 'test-doc', drawingId: 'shape-1' }]); expect(await testBed.commandService.executeCommand(DeleteDocDrawingsCommand.id)).toBe(true); - await waitNextTick(); + await awaitTime(0); const doc = testBed.get(IUniverInstanceService) .getUnit('test-doc', UniverInstanceType.UNIVER_DOC)!; @@ -243,7 +240,7 @@ describe('docs drawing commands integration', () => { expect(await testBed.commandService.executeCommand(MoveDocDrawingsCommand.id, { direction: Direction.RIGHT, })).toBe(true); - await waitNextTick(); + await awaitTime(0); const doc = testBed.get(IUniverInstanceService) .getUnit('test-doc', UniverInstanceType.UNIVER_DOC)!; @@ -270,7 +267,7 @@ describe('docs drawing commands integration', () => { distR: 10, }, })).toBe(true); - await waitNextTick(); + await awaitTime(0); const doc = testBed.get(IUniverInstanceService) .getUnit('test-doc', UniverInstanceType.UNIVER_DOC)!; @@ -296,7 +293,7 @@ describe('docs drawing commands integration', () => { }], wrapText: WrapTextType.RIGHT, })).toBe(true); - await waitNextTick(); + await awaitTime(0); const doc = testBed.get(IUniverInstanceService) .getUnit('test-doc', UniverInstanceType.UNIVER_DOC)!; @@ -320,7 +317,7 @@ describe('docs drawing commands integration', () => { }, }], })).toBe(true); - await waitNextTick(); + await awaitTime(0); const doc = testBed.get(IUniverInstanceService) .getUnit('test-doc', UniverInstanceType.UNIVER_DOC)!; diff --git a/packages/docs-hyper-link-ui/src/__tests__/docs-hyper-link-ui.integration.spec.ts b/packages/docs-hyper-link-ui/src/__tests__/docs-hyper-link-ui.integration.spec.ts index 61930e9ef7..0842d63ab2 100644 --- a/packages/docs-hyper-link-ui/src/__tests__/docs-hyper-link-ui.integration.spec.ts +++ b/packages/docs-hyper-link-ui/src/__tests__/docs-hyper-link-ui.integration.spec.ts @@ -16,6 +16,7 @@ import type { DocumentDataModel, ICommand, IDisposable, IDocumentData, Injector } from '@univerjs/core'; import { + awaitTime, CustomRangeType, ICommandService, IUniverInstanceService, @@ -32,10 +33,6 @@ import { DocHyperLinkSelectionController } from '../controllers/doc-hyper-link-s import { DocHyperLinkPopupService } from '../services/hyper-link-popup.service'; import { createDocUiTestBed } from './create-doc-ui-test-bed'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function createDocData(): IDocumentData { return { id: 'test-doc', @@ -134,7 +131,7 @@ describe('docs-hyper-link-ui integration', () => { unitId: 'test-doc', payload: 'https://added.invalid', })).toBeTruthy(); - await waitNextTick(); + await awaitTime(0); const addedLink = getBody(get)?.customRanges?.find((range) => range.properties?.url === 'https://added.invalid'); expect(addedLink).toBeDefined(); @@ -160,7 +157,7 @@ describe('docs-hyper-link-ui integration', () => { label: 'planet', segmentId: '', })).toBeTruthy(); - await waitNextTick(); + await awaitTime(0); expect(getBody(get)?.dataStream).toBe('Hello planet\r\n'); expect(getBody(get)?.customRanges?.find((range) => range.rangeId === 'link-1')?.properties).toEqual({ @@ -175,7 +172,7 @@ describe('docs-hyper-link-ui integration', () => { unitId: 'test-doc', linkId: 'link-1', })).toBeTruthy(); - await waitNextTick(); + await awaitTime(0); expect(getBody(get)?.dataStream).toBe('Hello world\r\n'); expect(getBody(get)?.customRanges?.some((range) => range.rangeId === 'link-1')).toBe(false); diff --git a/packages/docs-mention-ui/src/__tests__/docs-mention-ui.integration.spec.ts b/packages/docs-mention-ui/src/__tests__/docs-mention-ui.integration.spec.ts index 118075a316..12a59917bc 100644 --- a/packages/docs-mention-ui/src/__tests__/docs-mention-ui.integration.spec.ts +++ b/packages/docs-mention-ui/src/__tests__/docs-mention-ui.integration.spec.ts @@ -15,7 +15,7 @@ */ import type { ICommand, IDisposable, IDocumentData, Univer } from '@univerjs/core'; -import { CustomRangeType, Direction, ICommandService, IUniverInstanceService } from '@univerjs/core'; +import { awaitTime, CustomRangeType, Direction, ICommandService, IUniverInstanceService } from '@univerjs/core'; import { DocSelectionManagerService, RichTextEditingMutation, SetTextSelectionsOperation } from '@univerjs/docs'; import { DocCanvasPopManagerService, InsertCommand, MoveCursorOperation } from '@univerjs/docs-ui'; import { afterEach, describe, expect, it, vi } from 'vitest'; @@ -29,10 +29,6 @@ import { DocMentionPopupService } from '../services/doc-mention-popup.service'; import { DocMentionService } from '../services/doc-mention.service'; import { createDocUiTestBed } from './create-doc-ui-test-bed'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function createTriggerDocData(): IDocumentData { return { id: 'test-doc', @@ -236,7 +232,7 @@ describe('docs-mention-ui integration', () => { }, }, })).toBeTruthy(); - await waitNextTick(); + await awaitTime(0); const documentBody = testBed.get(IUniverInstanceService) .getCurrentUniverDocInstance() @@ -288,7 +284,7 @@ describe('docs-mention-ui integration', () => { unitId: 'test-doc', mentionId: 'mention-1', })).toBeTruthy(); - await waitNextTick(); + await awaitTime(0); const docBody = testBed.get(IUniverInstanceService) .getCurrentUniverDocInstance() diff --git a/packages/docs-ui/src/commands/commands/__tests__/break-line.command.spec.ts b/packages/docs-ui/src/commands/commands/__tests__/break-line.command.spec.ts index 14a2f09501..89bc5ee4be 100644 --- a/packages/docs-ui/src/commands/commands/__tests__/break-line.command.spec.ts +++ b/packages/docs-ui/src/commands/commands/__tests__/break-line.command.spec.ts @@ -15,16 +15,12 @@ */ import type { DocumentDataModel, ICommand, IDocumentData, Injector, Univer } from '@univerjs/core'; -import { ICommandService, IUniverInstanceService, NamedStyleType, UniverInstanceType } from '@univerjs/core'; +import { awaitTime, ICommandService, IUniverInstanceService, NamedStyleType, UniverInstanceType } from '@univerjs/core'; import { DocSelectionManagerService, RichTextEditingMutation, SetTextSelectionsOperation } from '@univerjs/docs'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { BreakLineCommand } from '../break-line.command'; import { createCommandTestBed } from './create-command-test-bed'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function getDocumentData(): IDocumentData { return { id: 'test-doc', @@ -89,7 +85,7 @@ describe('break line command', () => { it('splits a heading paragraph and resets heading style for the new paragraph', async () => { await commandService.executeCommand(BreakLineCommand.id); - await waitNextTick(); + await awaitTime(0); expect(getParagraphs()).toHaveLength(2); expect(getParagraphs()[0].paragraphStyle?.namedStyleType).toBe(NamedStyleType.HEADING_1); diff --git a/packages/docs-ui/src/commands/commands/__tests__/core-editing.command.spec.ts b/packages/docs-ui/src/commands/commands/__tests__/core-editing.command.spec.ts index 8aaaa0ec58..4b13236343 100644 --- a/packages/docs-ui/src/commands/commands/__tests__/core-editing.command.spec.ts +++ b/packages/docs-ui/src/commands/commands/__tests__/core-editing.command.spec.ts @@ -16,6 +16,7 @@ import type { DocumentDataModel, ICommand, IDocumentData, Injector, IStyleBase, Univer } from '@univerjs/core'; import { + awaitTime, BooleanNumber, CustomRangeType, ICommandService, @@ -29,10 +30,6 @@ import { DeleteDirection } from '../../../types/delete-direction'; import { DeleteCommand, InsertCommand, UpdateCommand } from '../core-editing.command'; import { createCommandTestBed } from './create-command-test-bed'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function getDocumentData(): IDocumentData { return { id: 'test-doc', @@ -124,7 +121,7 @@ describe('core editing commands', () => { }, }); - await waitNextTick(); + await awaitTime(0); expect(getDataStream()).toBe('Hello, brave world\r\n'); }); @@ -137,7 +134,7 @@ describe('core editing commands', () => { direction: DeleteDirection.RIGHT, }); - await waitNextTick(); + await awaitTime(0); expect(getDataStream()).toBe('Hello \r\n'); expect(getBody()?.customRanges).toEqual([]); @@ -166,7 +163,7 @@ describe('core editing commands', () => { }], }); - await waitNextTick(); + await awaitTime(0); expect(getDataStream()).toBe('Hello world\r\n'); expect(getFormatValueAt('bl', 1)).toBe(BooleanNumber.TRUE); diff --git a/packages/docs-ui/src/commands/commands/__tests__/list.command.spec.ts b/packages/docs-ui/src/commands/commands/__tests__/list.command.spec.ts index 96f51a4bbe..8441fe9bc2 100644 --- a/packages/docs-ui/src/commands/commands/__tests__/list.command.spec.ts +++ b/packages/docs-ui/src/commands/commands/__tests__/list.command.spec.ts @@ -15,7 +15,7 @@ */ import type { DocumentDataModel, ICommand, IDocumentData, Injector, Univer } from '@univerjs/core'; -import { ICommandService, IUniverInstanceService, PRESET_LIST_TYPE, PresetListType, UniverInstanceType } from '@univerjs/core'; +import { awaitTime, ICommandService, IUniverInstanceService, PRESET_LIST_TYPE, PresetListType, UniverInstanceType } from '@univerjs/core'; import { DocSelectionManagerService, RichTextEditingMutation, SetTextSelectionsOperation } from '@univerjs/docs'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { @@ -31,10 +31,6 @@ import { } from '../list.command'; import { createCommandTestBed } from './create-command-test-bed'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function getDocumentData(): IDocumentData { return { id: 'test-doc', @@ -107,7 +103,7 @@ describe('list commands', () => { ]); await commandService.executeCommand(BulletListCommand.id); - await waitNextTick(); + await awaitTime(0); const paragraphs = getBody()?.paragraphs ?? []; expect(paragraphs[0].bullet?.listType).toBe(PresetListType.BULLET_LIST); @@ -128,7 +124,7 @@ describe('list commands', () => { await commandService.executeCommand(ChangeListNestingLevelCommand.id, { type: ChangeListNestingLevelType.increase, }); - await waitNextTick(); + await awaitTime(0); const paragraphs = getBody()?.paragraphs ?? []; expect(paragraphs[0].bullet?.listType).toBe(PresetListType.CHECK_LIST_CHECKED); @@ -139,7 +135,7 @@ describe('list commands', () => { setSelections([{ startOffset: 0, endOffset: 4, collapsed: false }]); await commandService.executeCommand(CheckListCommand.id); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.paragraphs?.[0].bullet?.listType).toBe(PresetListType.CHECK_LIST); @@ -154,7 +150,7 @@ describe('list commands', () => { listType: PresetListType.ORDER_LIST, paragraph, }); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.paragraphs?.[0].bullet?.listType).toBe(PresetListType.ORDER_LIST); expect(getBody()?.paragraphs?.[0].bullet?.listId).toBeDefined(); diff --git a/packages/docs-ui/src/commands/commands/__tests__/misc.command.spec.ts b/packages/docs-ui/src/commands/commands/__tests__/misc.command.spec.ts index 7275555cda..d987aac803 100644 --- a/packages/docs-ui/src/commands/commands/__tests__/misc.command.spec.ts +++ b/packages/docs-ui/src/commands/commands/__tests__/misc.command.spec.ts @@ -17,6 +17,7 @@ import type { DocumentDataModel, ICommand, IDocumentData, Injector, Univer } from '@univerjs/core'; import type { IAutoFormat } from '../../../services/doc-auto-format.service'; import { + awaitTime, CommandType, CustomRangeType, HorizontalAlign, @@ -41,10 +42,6 @@ import { SetDocZoomRatioCommand } from '../set-doc-zoom-ratio.command'; import { genEmptyTable } from '../table/table'; import { createCommandTestBed } from './create-command-test-bed'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function createBaseDoc(dataStream = 'Hello world\r\n'): IDocumentData { return { id: 'test-doc', @@ -218,7 +215,7 @@ describe('misc document commands', () => { wholeEntity: true, }); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.dataStream).toBe('Hello@OpenAI\r\n'); expect(getBody()?.customRanges).toEqual([expect.objectContaining({ @@ -248,7 +245,7 @@ describe('misc document commands', () => { }, }); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.paragraphs?.[0].paragraphStyle).toEqual(expect.objectContaining({ namedStyleType: NamedStyleType.HEADING_1, @@ -277,7 +274,7 @@ describe('misc document commands', () => { }); const result = await commandService.executeCommand(DocSelectAllCommand.id); - await waitNextTick(); + await awaitTime(0); expect(result).toBe(true); expect(refreshEvents.at(-1)).toEqual(expect.objectContaining({ @@ -308,7 +305,7 @@ describe('misc document commands', () => { }); const result = await commandService.executeCommand(DocSelectAllCommand.id); - await waitNextTick(); + await awaitTime(0); expect(result).toBe(true); expect(refreshEvents.at(-1)).toEqual(expect.objectContaining({ @@ -352,7 +349,7 @@ describe('misc document commands', () => { }, }); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.paragraphs).toHaveLength(3); expect(getBody()?.paragraphs?.[0].paragraphStyle?.borderBottom).toEqual(expect.objectContaining({ width: 1, @@ -371,7 +368,7 @@ describe('misc document commands', () => { await commandService.executeCommand(InsertHorizontalLineBellowCommand.id); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.paragraphs).toHaveLength(3); expect(getBody()?.paragraphs?.[1].paragraphStyle?.borderBottom).toEqual(expect.objectContaining({ width: 1, @@ -389,19 +386,19 @@ describe('misc document commands', () => { setCollapsedSelection(0, 10); await commandService.executeCommand(AlignCenterCommand.id); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.paragraphs?.[0].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.CENTER); expect(getBody()?.paragraphs?.[1].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.CENTER); await commandService.executeCommand(AlignCenterCommand.id); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.paragraphs?.[0].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.UNSPECIFIED); expect(getBody()?.paragraphs?.[1].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.UNSPECIFIED); await commandService.executeCommand(AlignJustifyCommand.id); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.paragraphs?.[0].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.JUSTIFIED); expect(getBody()?.paragraphs?.[1].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.JUSTIFIED); diff --git a/packages/docs-ui/src/commands/commands/__tests__/set-heading.command.spec.ts b/packages/docs-ui/src/commands/commands/__tests__/set-heading.command.spec.ts index 864e3da285..473dcf9764 100644 --- a/packages/docs-ui/src/commands/commands/__tests__/set-heading.command.spec.ts +++ b/packages/docs-ui/src/commands/commands/__tests__/set-heading.command.spec.ts @@ -15,16 +15,12 @@ */ import type { DocumentDataModel, ICommand, IDocumentData, Injector, Univer } from '@univerjs/core'; -import { ICommandService, IUniverInstanceService, NamedStyleType, UniverInstanceType } from '@univerjs/core'; +import { awaitTime, ICommandService, IUniverInstanceService, NamedStyleType, UniverInstanceType } from '@univerjs/core'; import { DocSelectionManagerService, RichTextEditingMutation, SetTextSelectionsOperation } from '@univerjs/docs'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { H1HeadingCommand, QuickHeadingCommand, SetParagraphNamedStyleCommand } from '../set-heading.command'; import { createCommandTestBed } from './create-command-test-bed'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function getHeadingDocumentData(): IDocumentData { return { id: 'test-doc', @@ -106,7 +102,7 @@ describe('set heading commands', () => { await commandService.executeCommand(H1HeadingCommand.id); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.paragraphs?.[0].paragraphStyle?.namedStyleType).toBe(NamedStyleType.HEADING_1); expect(getBody()?.paragraphs?.[0].paragraphStyle?.headingId).toBeDefined(); @@ -136,7 +132,7 @@ describe('set heading commands', () => { value: NamedStyleType.HEADING_2, }); - await waitNextTick(); + await awaitTime(0); expect(getBody()?.dataStream.startsWith('Heading')).toBe(true); expect(getBody()?.paragraphs?.[0].paragraphStyle?.namedStyleType).toBe(NamedStyleType.HEADING_2); diff --git a/packages/docs-ui/src/controllers/__tests__/doc-ime-input.controller.spec.ts b/packages/docs-ui/src/controllers/__tests__/doc-ime-input.controller.spec.ts index 85d2e74207..b10ece5f36 100644 --- a/packages/docs-ui/src/controllers/__tests__/doc-ime-input.controller.spec.ts +++ b/packages/docs-ui/src/controllers/__tests__/doc-ime-input.controller.spec.ts @@ -14,16 +14,13 @@ * limitations under the License. */ +import { awaitTime } from '@univerjs/core'; import { RichTextEditingMutation } from '@univerjs/docs'; import { Subject } from 'rxjs'; import { describe, expect, it, vi } from 'vitest'; import { IMEInputCommand } from '../../commands/commands/ime-input.command'; import { DocIMEInputController } from '../render-controllers/doc-ime-input.controller'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function createRange() { return { startOffset: 0, @@ -81,12 +78,12 @@ describe('doc ime input controller', () => { event: { data: '한' }, activeRange, }); - await waitNextTick(); + await awaitTime(0); onCompositionend$.next({ event: { data: '한' }, activeRange, }); - await waitNextTick(); + await awaitTime(0); expect(commandService.executeCommand).toHaveBeenCalledTimes(1); expect(commandService.executeCommand).toHaveBeenCalledWith(IMEInputCommand.id, { @@ -161,12 +158,12 @@ describe('doc ime input controller', () => { event: { data: 'ㅎ' }, activeRange, }); - await waitNextTick(); + await awaitTime(0); onCompositionend$.next({ event: { data: '한' }, activeRange, }); - await waitNextTick(); + await awaitTime(0); expect(commandService.executeCommand).toHaveBeenCalledTimes(2); expect(commandService.executeCommand).toHaveBeenNthCalledWith(2, IMEInputCommand.id, { diff --git a/packages/docs-ui/src/services/clipboard/clipboard.service.ts b/packages/docs-ui/src/services/clipboard/clipboard.service.ts index e57395edcd..b47cf2bddb 100644 --- a/packages/docs-ui/src/services/clipboard/clipboard.service.ts +++ b/packages/docs-ui/src/services/clipboard/clipboard.service.ts @@ -53,7 +53,7 @@ import { } from '@univerjs/ui'; import { CutContentCommand, InnerPasteCommand } from '../../commands/commands/clipboard.inner.command'; import { getCursorWhenDelete } from '../../commands/commands/doc-delete.command'; -import { copyContentCache, extractId, genId } from './copy-content-cache'; +import { copyContentCache, extractId } from './copy-content-cache'; import { HtmlToUDMService } from './html-to-udm/converter'; import LarkPastePlugin from './html-to-udm/paste-plugins/plugin-lark'; import UniverPastePlugin from './html-to-udm/paste-plugins/plugin-univer'; @@ -327,7 +327,7 @@ export class DocClipboardService extends Disposable implements IDocClipboardServ } private async _setClipboardData(documentList: IDocumentData[], needCache = true): Promise { - const copyId = genId(); + const copyId = generateRandomId(6); const text = (documentList.length > 1 ? documentList.map((doc) => doc.body?.dataStream || '').join('\n') diff --git a/packages/docs-ui/src/services/clipboard/copy-content-cache.ts b/packages/docs-ui/src/services/clipboard/copy-content-cache.ts index 67397348a7..dacfe4113d 100644 --- a/packages/docs-ui/src/services/clipboard/copy-content-cache.ts +++ b/packages/docs-ui/src/services/clipboard/copy-content-cache.ts @@ -15,14 +15,9 @@ */ import type { IDocumentData } from '@univerjs/core'; -import { generateRandomId, LRUMap } from '@univerjs/core'; +import { LRUMap } from '@univerjs/core'; const COPY_CONTENT_CACHE_LIMIT = 10; -const ID_LENGTH = 6; - -export function genId() { - return generateRandomId(ID_LENGTH); -} export function extractId(html: string) { const match = html.match(/data-copy-id="([^\s]+)"/); diff --git a/packages/docs/src/__tests__/docs.integration.spec.ts b/packages/docs/src/__tests__/docs.integration.spec.ts index 8abb93ccce..358a7f0018 100644 --- a/packages/docs/src/__tests__/docs.integration.spec.ts +++ b/packages/docs/src/__tests__/docs.integration.spec.ts @@ -16,8 +16,8 @@ import type { DocumentDataModel, ICustomRangeForInterceptor, IDocumentData, IInterceptor } from '@univerjs/core'; import type { IRenderContext } from '@univerjs/engine-render'; - import { + awaitTime, CustomRangeType, ICommandService, IUniverInstanceService, @@ -29,7 +29,6 @@ import { } from '@univerjs/core'; import { IRenderManagerService } from '@univerjs/engine-render'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; - import { DocsRenameMutation } from '../commands/mutations/docs-rename.mutation'; import { SetTextSelectionsOperation } from '../commands/operations/text-selection.operation'; import { UniverDocsPlugin } from '../plugin'; @@ -42,10 +41,6 @@ import { DocViewModelManagerService } from '../services/doc-view-model-manager.s import { addCustomRangeBySelectionFactory, deleteCustomRangeFactory } from '../utils/custom-range-factory'; import { replaceSelectionFactory } from '../utils/replace-selection-factory'; -function waitNextTick() { - return new Promise((resolve) => setTimeout(resolve, 0)); -} - function registerRenderManagerForDoc( injector: ReturnType, doc: DocumentDataModel @@ -197,7 +192,7 @@ describe('docs integration', () => { { unitId: doc.getUnitId(), subUnitId: doc.getUnitId() } ); - await waitNextTick(); + await awaitTime(0); expect(executed.some((e) => e.id === SetTextSelectionsOperation.id)).toBe(true); dispose.dispose(); }); @@ -250,7 +245,7 @@ describe('docs integration', () => { trigger: 'integration-spec' as never, }); - await waitNextTick(); + await awaitTime(0); expect(ok).toBeTruthy(); expect(doc.getBody()?.dataStream).toBe('Hello world\r\n'); diff --git a/packages/engine-render/src/engine.ts b/packages/engine-render/src/engine.ts index ca4da4f53b..52804b4c2e 100644 --- a/packages/engine-render/src/engine.ts +++ b/packages/engine-render/src/engine.ts @@ -15,13 +15,12 @@ */ import type { IDisposable, Nullable } from '@univerjs/core'; - import type { CURSOR_TYPE } from './basics/const'; import type { IEvent, IKeyboardEvent, IPointerEvent } from './basics/i-events'; import type { ITimeMetric, ITransformChangeState } from './basics/interfaces'; import type { IBasicFrameInfo } from './basics/performance-monitor'; import type { Scene } from './scene'; -import { Disposable, EventSubject, toDisposable, Tools } from '@univerjs/core'; +import { Disposable, EventSubject, noop, toDisposable, Tools } from '@univerjs/core'; import { Observable, shareReplay, Subject } from 'rxjs'; import { RENDER_CLASS_TYPE } from './basics/const'; import { DeviceType, PointerInput } from './basics/i-events'; @@ -989,7 +988,6 @@ export class Engine extends Disposable { // IE11 only supports captureEvent:boolean, not options:object, and it defaults to false. // Feature detection technique copied from: https://github.com/github/eventlistener-polyfill (MIT license) let passiveSupported = false; - const noop = () => { /* empty */ }; try { const options: object = { diff --git a/packages/find-replace/src/services/__tests__/find-replace.service.spec.ts b/packages/find-replace/src/services/__tests__/find-replace.service.spec.ts index 064b6728cf..54ef86950a 100644 --- a/packages/find-replace/src/services/__tests__/find-replace.service.spec.ts +++ b/packages/find-replace/src/services/__tests__/find-replace.service.spec.ts @@ -15,8 +15,9 @@ */ import type { FindModel, IFindMatch } from '../find-replace.service'; -import { Subject } from 'rxjs'; +import { awaitTime } from '@univerjs/core'; +import { Subject } from 'rxjs'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { FindBy, FindDirection, FindReplaceModel, FindReplaceService, FindScope } from '../find-replace.service'; @@ -78,7 +79,7 @@ describe('FindReplaceService', () => { service.find(); // wait for provider find to resolve - await new Promise((r) => setTimeout(r, 0)); + await awaitTime(0); service.moveToNextMatch(); expect(service.getCurrentMatch()).toEqual(match1); diff --git a/packages/network/src/services/http/interceptors/merge-interceptor.ts b/packages/network/src/services/http/interceptors/merge-interceptor.ts index 85c70ac758..a856e56729 100644 --- a/packages/network/src/services/http/interceptors/merge-interceptor.ts +++ b/packages/network/src/services/http/interceptors/merge-interceptor.ts @@ -16,11 +16,11 @@ import type { HTTPHandlerFn } from '../interceptor'; import type { HTTPRequest } from '../request'; +import { noop } from '@univerjs/core'; import { Observable } from 'rxjs'; import { HTTPEventType, HTTPResponse } from '../response'; const createDefaultFetchCheck = (time = 300) => { - const noop = () => { }; let cancel = noop; return (_currentConfig: HTTPRequest) => { return new Promise((res) => { diff --git a/packages/rpc/src/services/rpc/__tests__/channel.service.spec.ts b/packages/rpc/src/services/rpc/__tests__/channel.service.spec.ts index 1a36ec645b..45c3ee85fe 100644 --- a/packages/rpc/src/services/rpc/__tests__/channel.service.spec.ts +++ b/packages/rpc/src/services/rpc/__tests__/channel.service.spec.ts @@ -15,17 +15,12 @@ */ import type { IMessageProtocol } from '../rpc.service'; +import { awaitTime } from '@univerjs/core'; import { Observable, Subject } from 'rxjs'; import { describe, expect, it } from 'vitest'; import { ChannelService } from '../channel.service'; import { fromModule } from '../rpc.service'; -function flushPromises() { - return new Promise((resolve) => { - setTimeout(() => resolve(), 0); - }); -} - describe('ChannelService', () => { it('should register channel, request channel, and dispose', async () => { const message$ = new Subject(); @@ -55,7 +50,7 @@ describe('ChannelService', () => { const values: number[] = []; channel.subscribe('values$').subscribe((value) => values.push(value)); - await flushPromises(); + await awaitTime(0); expect(values).toEqual([1]); service.dispose(); diff --git a/packages/rpc/src/services/rpc/__tests__/rpc.service.edge.spec.ts b/packages/rpc/src/services/rpc/__tests__/rpc.service.edge.spec.ts index 3a942181b7..125ecd33da 100644 --- a/packages/rpc/src/services/rpc/__tests__/rpc.service.edge.spec.ts +++ b/packages/rpc/src/services/rpc/__tests__/rpc.service.edge.spec.ts @@ -15,6 +15,7 @@ */ import type { IChannel, IMessageProtocol } from '../rpc.service'; +import { awaitTime } from '@univerjs/core'; import { Observable, Subject } from 'rxjs'; import { describe, expect, it, vi } from 'vitest'; import { ChannelClient, ChannelServer, fromModule, toModule } from '../rpc.service'; @@ -31,12 +32,6 @@ const SUBSCRIBE_NEXT = 300; const SUBSCRIBE_ERROR = 301; const SUBSCRIBE_COMPLETE = 302; -function flushPromises() { - return new Promise((resolve) => { - setTimeout(() => resolve(), 0); - }); -} - function getType(value: unknown): number | undefined { if (typeof value !== 'object' || value === null) { return undefined; @@ -128,7 +123,7 @@ describe('rpc.service edge cases', () => { lazySubscription.unsubscribe(); protocol.emit({ seq: -1, type: INITIALIZE }); - await flushPromises(); + await awaitTime(0); const callRequest = protocol.sent.find((msg) => getType(msg) === CALL); expect(callRequest).toBeDefined(); @@ -198,7 +193,7 @@ describe('rpc.service edge cases', () => { protocol.emit({ type: 999, seq: 1, channelName: '', method: '' }); protocol.emit({ type: CALL, seq: 10, channelName: 'missing', method: 'm' }); - await flushPromises(); + await awaitTime(0); expect(protocol.sent).toContainEqual({ seq: 10, type: CALL_FAILURE, @@ -213,7 +208,7 @@ describe('rpc.service edge cases', () => { subscribe: () => new Observable(), } as IChannel); protocol.emit({ type: CALL, seq: 11, channelName: 'bad-call', method: 'm', args: [] }); - await flushPromises(); + await awaitTime(0); expect(protocol.sent).toContainEqual({ seq: 11, type: CALL_FAILURE, @@ -225,7 +220,7 @@ describe('rpc.service edge cases', () => { subscribe: () => new Observable(), } as IChannel); protocol.emit({ type: CALL, seq: 12, channelName: 'no-args', method: 'm' }); - await flushPromises(); + await awaitTime(0); expect(protocol.sent).toContainEqual({ seq: 12, type: CALL_SUCCESS, diff --git a/packages/sheets-data-validation-ui/src/controllers/__tests__/dv-rerender.controller.spec.ts b/packages/sheets-data-validation-ui/src/controllers/__tests__/dv-rerender.controller.spec.ts index 81ce416017..4ee58ee92b 100644 --- a/packages/sheets-data-validation-ui/src/controllers/__tests__/dv-rerender.controller.spec.ts +++ b/packages/sheets-data-validation-ui/src/controllers/__tests__/dv-rerender.controller.spec.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { awaitTime } from '@univerjs/core'; import { Subject } from 'rxjs'; import { describe, expect, it, vi } from 'vitest'; import { SheetsDataValidationReRenderController } from '../dv-rerender.controller'; @@ -42,7 +43,7 @@ describe('SheetsDataValidationReRenderController', () => { validStatusChange$.next({ subUnitId: 'sheet-1' }); expect(controller).toBeTruthy(); - await new Promise((resolve) => setTimeout(resolve, 30)); + await awaitTime(30); expect(makeDirty1).toHaveBeenCalledTimes(1); expect(makeDirty2).toHaveBeenCalledTimes(1); diff --git a/packages/sheets-data-validation-ui/src/views/components/formula-input/ListFormulaInput.tsx b/packages/sheets-data-validation-ui/src/views/components/formula-input/ListFormulaInput.tsx index 684f26a131..b6793a7666 100644 --- a/packages/sheets-data-validation-ui/src/views/components/formula-input/ListFormulaInput.tsx +++ b/packages/sheets-data-validation-ui/src/views/components/formula-input/ListFormulaInput.tsx @@ -17,7 +17,7 @@ import type { IFormulaInputProps } from '@univerjs/data-validation'; import type { ListValidator } from '@univerjs/sheets-data-validation'; import type { IFormulaEditorRef } from '@univerjs/sheets-formula-ui'; -import { DataValidationType, generateRandomId, isFormulaString, LocaleService } from '@univerjs/core'; +import { awaitTime, DataValidationType, generateRandomId, isFormulaString, LocaleService } from '@univerjs/core'; import { DataValidationModel, DataValidatorRegistryService } from '@univerjs/data-validation'; import { borderClassName, clsx, DraggableList, Dropdown, FormLayout, Input, Radio, RadioGroup } from '@univerjs/design'; import { DeleteIcon, IncreaseIcon, MoreDownIcon, SequenceIcon } from '@univerjs/icons'; @@ -185,9 +185,7 @@ export function ListFormulaInput(props: IFormulaInputProps) { useEffect(() => { (async () => { - await new Promise((resolve) => { - setTimeout(() => resolve(true), 100); - }); + await awaitTime(100); const rule = dataValidationModel.getRuleById(unitId, subUnitId, ruleId); const formula1 = rule?.formula1; diff --git a/packages/sheets-filter-ui/src/services/__tests__/sheets-filter-panel.service.spec.ts b/packages/sheets-filter-ui/src/services/__tests__/sheets-filter-panel.service.spec.ts index 28492bf992..005927cd65 100644 --- a/packages/sheets-filter-ui/src/services/__tests__/sheets-filter-panel.service.spec.ts +++ b/packages/sheets-filter-ui/src/services/__tests__/sheets-filter-panel.service.spec.ts @@ -19,7 +19,7 @@ import type { IEditorBridgeServiceVisibleParam } from '@univerjs/sheets-ui'; import type { IOpenFilterPanelOperationParams } from '../../commands/operations/sheets-filter.operation'; import type { IFilterConditionFormParams } from '../../models/conditions'; import type { IFilterByValueWithTreeItem } from '../sheets-filter-panel.service'; -import { CommandType, ICommandService, Inject, Injector, LocaleService, Plugin, Univer, UniverInstanceType } from '@univerjs/core'; +import { awaitTime, CommandType, ICommandService, Inject, Injector, LocaleService, Plugin, Univer, UniverInstanceType } from '@univerjs/core'; import { ActiveDirtyManagerService, IActiveDirtyManagerService, ISheetRowFilteredService, SheetRowFilteredService } from '@univerjs/engine-formula'; import { MarkDirtyFilterChangeMutation, RefRangeService, SheetInterceptorService, SheetRangeThemeModel, SheetsSelectionsService, ZebraCrossingCacheController } from '@univerjs/sheets'; import { CustomFilterOperator, FilterBy, SheetsFilterService, UniverSheetsFilterPlugin } from '@univerjs/sheets-filter'; @@ -262,7 +262,7 @@ describe('test "SheetsFilterPanelService"', () => { subUnitId: 'sheet1', col: 0, } as IOpenFilterPanelOperationParams)).toBeTruthy(); - await await tick(); + await tick(); expect(sheetsFilterPanelService.filterBy).toBe(FilterBy.VALUES); const filterByModel = sheetsFilterPanelService.filterByModel as ByValuesModel; @@ -520,7 +520,7 @@ describe('test "SheetsFilterPanelService"', () => { }); function tick(milliseconds: number = 0): Promise { - const result = new Promise((resolve) => setTimeout(resolve, milliseconds)); + const result = awaitTime(milliseconds); vitest.advanceTimersByTime(milliseconds + 1); return result; } diff --git a/packages/sheets-filter-ui/src/worker/generate-filter-values.service.ts b/packages/sheets-filter-ui/src/worker/generate-filter-values.service.ts index bc1e99bb93..34d92ef90e 100644 --- a/packages/sheets-filter-ui/src/worker/generate-filter-values.service.ts +++ b/packages/sheets-filter-ui/src/worker/generate-filter-values.service.ts @@ -17,7 +17,17 @@ import type { IRange, Nullable, Styles, Workbook, Worksheet } from '@univerjs/core'; import type { FilterColumn } from '@univerjs/sheets-filter'; import type { IFilterByValueItem, IFilterByValueWithTreeItem } from '../services/sheets-filter-panel.service'; -import { createIdentifier, Disposable, extractPureTextFromCell, ILogService, Inject, IUniverInstanceService, LocaleService, numfmt } from '@univerjs/core'; +import { + createIdentifier, + Disposable, + extractPureTextFromCell, + ILogService, + Inject, + isNumeric, + IUniverInstanceService, + LocaleService, + numfmt, +} from '@univerjs/core'; import { FilterBy } from '@univerjs/sheets-filter'; export interface ISheetsGenerateFilterValuesService { @@ -335,8 +345,6 @@ function generateFilterTreeBySort(tree: IFilterByValueWithTreeItem[]) { }); } -const isNumeric = (str: string) => !Number.isNaN(Number(str)) && !Number.isNaN(Number.parseFloat(str)); ; - function compare(strA: string, strB: string) { const aIsNumeric = isNumeric(strA); const bIsNumeric = isNumeric(strB); diff --git a/packages/sheets-formula-ui/src/views/formula-editor/help-function/HelpFunction.tsx b/packages/sheets-formula-ui/src/views/formula-editor/help-function/HelpFunction.tsx index 28138c9c83..8eae9d346b 100644 --- a/packages/sheets-formula-ui/src/views/formula-editor/help-function/HelpFunction.tsx +++ b/packages/sheets-formula-ui/src/views/formula-editor/help-function/HelpFunction.tsx @@ -16,7 +16,7 @@ import type { Editor } from '@univerjs/docs-ui'; import type { IFunctionParam } from '@univerjs/engine-formula'; -import { LocaleService } from '@univerjs/core'; +import { LocaleService, noop } from '@univerjs/core'; import { borderClassName, borderTopClassName, clsx, scrollbarClassName } from '@univerjs/design'; import { CloseIcon, MoreIcon } from '@univerjs/icons'; import { IEditorBridgeService } from '@univerjs/sheets-ui'; @@ -91,7 +91,6 @@ interface IHelpFunctionProps { formulaText: string; }; -const noop = () => { }; export function HelpFunction(props: IHelpFunctionProps) { const { onParamsSwitch = noop, onClose: propColose = noop, isFocus, editor, formulaText } = props; const { functionInfo, paramIndex, reset } = useFormulaDescribe(isFocus, formulaText, editor); diff --git a/packages/sheets-formula-ui/src/views/formula-editor/hooks/use-sheet-selection-change.ts b/packages/sheets-formula-ui/src/views/formula-editor/hooks/use-sheet-selection-change.ts index f5f5f9d3bb..45e3400060 100644 --- a/packages/sheets-formula-ui/src/views/formula-editor/hooks/use-sheet-selection-change.ts +++ b/packages/sheets-formula-ui/src/views/formula-editor/hooks/use-sheet-selection-change.ts @@ -21,9 +21,25 @@ import type { Editor } from '@univerjs/docs-ui'; import type { ISelectionWithCoord, ISetSelectionsOperationParams } from '@univerjs/sheets'; import type { RefObject } from 'react'; import type { IRefSelection } from './use-highlight'; -import { DisposableCollection, ICommandService, IUniverInstanceService, Rectangle, ThemeService, UniverInstanceType } from '@univerjs/core'; +import { + DisposableCollection, + ICommandService, + IUniverInstanceService, + noop, + Rectangle, + ThemeService, + UniverInstanceType, +} from '@univerjs/core'; import { DocSelectionManagerService } from '@univerjs/docs'; -import { deserializeRangeWithSheet, generateStringWithSequence, LexerTreeBuilder, sequenceNodeType, serializeRange, serializeRangeWithSheet, serializeRangeWithSpreadsheet } from '@univerjs/engine-formula'; +import { + deserializeRangeWithSheet, + generateStringWithSequence, + LexerTreeBuilder, + sequenceNodeType, + serializeRange, + serializeRangeWithSheet, + serializeRangeWithSpreadsheet, +} from '@univerjs/engine-formula'; import { IRenderManagerService } from '@univerjs/engine-render'; import { IRefSelectionsService, SetSelectionsOperation } from '@univerjs/sheets'; import { SheetSkeletonManagerService } from '@univerjs/sheets-ui'; @@ -60,7 +76,6 @@ const prepareSelectionChangeContext = (opts: { editor?: Editor; lexerTreeBuilder }; }; -const noop = (() => { }) as any; export const useSheetSelectionChange = ( isNeed: boolean, isFocus: boolean, @@ -71,7 +86,7 @@ export const useSheetSelectionChange = ( isSupportAcrossSheet: boolean, listenSelectionSet: boolean, editor?: Editor, - handleRangeChange: ((refString: string, offset: number, isEnd: boolean, isModify?: boolean) => void) = noop + handleRangeChange: ((refString: string, offset: number, isEnd: boolean, isModify?: boolean) => void) = noop as any ) => { const renderManagerService = useDependency(IRenderManagerService); const univerInstanceService = useDependency(IUniverInstanceService); diff --git a/packages/sheets-formula-ui/src/views/formula-editor/index.tsx b/packages/sheets-formula-ui/src/views/formula-editor/index.tsx index 90f2ac2f04..12b67ba920 100644 --- a/packages/sheets-formula-ui/src/views/formula-editor/index.tsx +++ b/packages/sheets-formula-ui/src/views/formula-editor/index.tsx @@ -21,7 +21,15 @@ import type { CSSProperties, ReactNode, Ref } from 'react'; import type { IUniverSheetsFormulaUIConfig } from '../../config/config'; import type { FormulaSelectingType } from './hooks/use-formula-selection'; import type { IRefSelection } from './hooks/use-highlight'; -import { BuildTextUtils, createInternalEditorID, generateRandomId, IConfigService, IUniverInstanceService, UniverInstanceType } from '@univerjs/core'; +import { + BuildTextUtils, + createInternalEditorID, + generateRandomId, + IConfigService, + IUniverInstanceService, + noop, + UniverInstanceType, +} from '@univerjs/core'; import { clsx } from '@univerjs/design'; import { DocBackScrollRenderController, DocSelectionRenderService, IEditorService, useKeyboardEvent, useResize } from '@univerjs/docs-ui'; import { IRenderManagerService } from '@univerjs/engine-render'; @@ -74,8 +82,6 @@ export interface IFormulaEditorProps { style?: CSSProperties; } -const noop = () => { }; - export interface IFormulaEditorRef { isClickOutSide: (e: MouseEvent) => boolean; } diff --git a/packages/sheets-formula-ui/src/views/formula-editor/search-function/SearchFunction.tsx b/packages/sheets-formula-ui/src/views/formula-editor/search-function/SearchFunction.tsx index baacd3bf9a..b188c82022 100644 --- a/packages/sheets-formula-ui/src/views/formula-editor/search-function/SearchFunction.tsx +++ b/packages/sheets-formula-ui/src/views/formula-editor/search-function/SearchFunction.tsx @@ -16,7 +16,7 @@ import type { Editor } from '@univerjs/docs-ui'; import type { FunctionType, ISequenceNode } from '@univerjs/engine-formula'; -import { CommandType, DisposableCollection, ICommandService } from '@univerjs/core'; +import { CommandType, DisposableCollection, ICommandService, noop } from '@univerjs/core'; import { borderClassName, clsx, scrollbarClassName } from '@univerjs/design'; import { DeviceInputEventType } from '@univerjs/engine-render'; import { IShortcutService, KeyCode, RectPopup, useDependency } from '@univerjs/ui'; @@ -36,7 +36,6 @@ interface ISearchFunctionProps { editor: Editor; onClose?: () => void; }; -const noop = () => { }; export const SearchFunction = forwardRef(SearchFunctionFactory); function SearchFunctionFactory(props: ISearchFunctionProps, ref: any) { const { isFocus, sequenceNodes, onSelect, editor, onClose = noop } = props; diff --git a/packages/sheets-formula/src/controllers/__tests__/image-formula-cell-interceptor.controller.spec.ts b/packages/sheets-formula/src/controllers/__tests__/image-formula-cell-interceptor.controller.spec.ts index d5a747b87d..72d4c87cac 100644 --- a/packages/sheets-formula/src/controllers/__tests__/image-formula-cell-interceptor.controller.spec.ts +++ b/packages/sheets-formula/src/controllers/__tests__/image-formula-cell-interceptor.controller.spec.ts @@ -16,11 +16,10 @@ import type { Dependency, IWorkbookData, Workbook, Worksheet } from '@univerjs/core'; import type { IImageFormulaInfo } from '@univerjs/engine-formula'; -import { CellValueType, ICommandService, InterceptorEffectEnum, LocaleType, ObjectMatrix } from '@univerjs/core'; +import { awaitTime, CellValueType, ICommandService, InterceptorEffectEnum, LocaleType, ObjectMatrix } from '@univerjs/core'; import { ErrorType, FormulaDataModel, SetImageFormulaDataMutation } from '@univerjs/engine-formula'; import { INTERCEPTOR_POINT, SheetInterceptorService } from '@univerjs/sheets'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; - import { createFacadeTestBed } from '../../facade/__tests__/create-test-bed'; import { ImageFormulaCellInterceptorController } from '../image-formula-cell-interceptor.controller'; @@ -75,7 +74,7 @@ async function waitForAssertion(assertion: () => void, timeout = 1000, interval assertion(); return; } catch { - await new Promise((resolve) => setTimeout(resolve, interval)); + await awaitTime(interval); } } diff --git a/packages/sheets-hyper-link-ui/src/controllers/__tests__/render.controller.spec.ts b/packages/sheets-hyper-link-ui/src/controllers/__tests__/render.controller.spec.ts index 4bd7208264..77743f822f 100644 --- a/packages/sheets-hyper-link-ui/src/controllers/__tests__/render.controller.spec.ts +++ b/packages/sheets-hyper-link-ui/src/controllers/__tests__/render.controller.spec.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { awaitTime } from '@univerjs/core'; import { Subject } from 'rxjs'; import { describe, expect, it, vi } from 'vitest'; import { SheetsHyperLinkRenderController } from '../render-controllers/render.controller'; @@ -30,7 +31,7 @@ describe('SheetsHyperLinkRenderController', () => { linkUpdate$.next(); // debounced by 16ms - await new Promise((resolve) => setTimeout(resolve, 30)); + await awaitTime(30); expect(makeForceDirty).toHaveBeenCalledTimes(1); controller.dispose(); diff --git a/packages/sheets-numfmt-ui/src/controllers/numfmt.editor.controller.ts b/packages/sheets-numfmt-ui/src/controllers/numfmt.editor.controller.ts index 21cebb2120..3442c04eb9 100644 --- a/packages/sheets-numfmt-ui/src/controllers/numfmt.editor.controller.ts +++ b/packages/sheets-numfmt-ui/src/controllers/numfmt.editor.controller.ts @@ -337,10 +337,6 @@ export class NumfmtEditorController extends Disposable { } } -function isNumeric(str: string) { - return /^-?\d+(\.\d+)?$/.test(str); -} - function canConvertRichTextToNumfmt(body: IDocumentBody): boolean { const { textRuns = [], paragraphs = [], customRanges, customBlocks = [] } = body; diff --git a/packages/sheets-ui/src/services/clipboard/__tests__/copy-content-cache.spec.ts b/packages/sheets-ui/src/services/clipboard/__tests__/copy-content-cache.spec.ts index d8cd25247d..f90e3cf41d 100644 --- a/packages/sheets-ui/src/services/clipboard/__tests__/copy-content-cache.spec.ts +++ b/packages/sheets-ui/src/services/clipboard/__tests__/copy-content-cache.spec.ts @@ -14,12 +14,13 @@ * limitations under the License. */ +import { generateRandomId } from '@univerjs/core'; import { describe, expect, it } from 'vitest'; -import { CopyContentCache, extractId, genId } from '../copy-content-cache'; +import { CopyContentCache, extractId } from '../copy-content-cache'; describe('copy-content-cache', () => { it('should generate id with expected length and extract id from html', () => { - const id = genId(); + const id = generateRandomId(6); expect(typeof id).toBe('string'); expect(id.length).toBe(6); diff --git a/packages/sheets-ui/src/services/clipboard/clipboard.service.ts b/packages/sheets-ui/src/services/clipboard/clipboard.service.ts index d18612548c..5aa734a64e 100644 --- a/packages/sheets-ui/src/services/clipboard/clipboard.service.ts +++ b/packages/sheets-ui/src/services/clipboard/clipboard.service.ts @@ -24,7 +24,12 @@ import type { Workbook, Worksheet, } from '@univerjs/core'; -import type { IDiscreteRange, ISetRangeValuesMutationParams, ISetSelectionsOperationParams, ISetWorksheetRowAutoHeightMutationParams } from '@univerjs/sheets'; +import type { + IDiscreteRange, + ISetRangeValuesMutationParams, + ISetSelectionsOperationParams, + ISetWorksheetRowAutoHeightMutationParams, +} from '@univerjs/sheets'; import type { Observable } from 'rxjs'; import type { ICellDataWithSpanInfo, @@ -46,6 +51,7 @@ import { Disposable, ErrorService, extractPureTextFromCell, + generateRandomId, getEmptyCell, ICommandService, ILogService, @@ -71,21 +77,40 @@ import { SetWorksheetRowAutoHeightMutationFactory, SheetsSelectionsService, } from '@univerjs/sheets'; -import { FILE__BMP_CLIPBOARD_MIME_TYPE, FILE__JPEG_CLIPBOARD_MIME_TYPE, FILE__WEBP_CLIPBOARD_MIME_TYPE, FILE_PNG_CLIPBOARD_MIME_TYPE, HTML_CLIPBOARD_MIME_TYPE, IClipboardInterfaceService, imageMimeTypeSet, INotificationService, IPlatformService, PLAIN_TEXT_CLIPBOARD_MIME_TYPE } from '@univerjs/ui'; +import { + FILE__BMP_CLIPBOARD_MIME_TYPE, + FILE__JPEG_CLIPBOARD_MIME_TYPE, + FILE__WEBP_CLIPBOARD_MIME_TYPE, + FILE_PNG_CLIPBOARD_MIME_TYPE, + HTML_CLIPBOARD_MIME_TYPE, + IClipboardInterfaceService, + imageMimeTypeSet, + INotificationService, + IPlatformService, + PLAIN_TEXT_CLIPBOARD_MIME_TYPE, +} from '@univerjs/ui'; import { BehaviorSubject } from 'rxjs'; import { virtualizeDiscreteRanges } from '../../controllers/utils/range-tools'; import { IMarkSelectionService } from '../mark-selection/mark-selection.service'; import { SheetSkeletonManagerService } from '../sheet-skeleton-manager.service'; import { createCopyPasteSelectionStyle } from '../utils/selection-util'; import { cloneCellDataWithSpanInfo } from './clone'; -import { CopyContentCache, extractId, genId } from './copy-content-cache'; +import { CopyContentCache, extractId } from './copy-content-cache'; import { HtmlToUSMService } from './html-to-usm/converter'; import { LarkPastePlugin } from './html-to-usm/paste-plugins/plugin-lark'; import { UniverPastePlugin } from './html-to-usm/paste-plugins/plugin-univer'; import { WordPastePlugin } from './html-to-usm/paste-plugins/plugin-word'; import { COPY_TYPE } from './type'; import { USMToHtmlService } from './usm-to-html/convertor'; -import { convertTextToTable, discreteRangeContainsRange, htmlContainsImage, htmlIsFromExcel, mergeSetRangeValues, rangeIntersectWithDiscreteRange, spilitLargeSetRangeValuesMutations } from './utils'; +import { + convertTextToTable, + discreteRangeContainsRange, + htmlContainsImage, + htmlIsFromExcel, + mergeSetRangeValues, + rangeIntersectWithDiscreteRange, + spilitLargeSetRangeValuesMutations, +} from './utils'; export const PREDEFINED_HOOK_NAME_COPY = { DEFAULT_COPY: 'default-copy', @@ -498,7 +523,7 @@ export class SheetClipboardService extends Disposable implements ISheetClipboard } // convert matrix to html - const copyId = genId(); + const copyId = generateRandomId(6); const html = this._usmToHtml.convert(matrix, discreteRange, hooks, copyId); const plain = getMatrixPlainText(plainMatrix); diff --git a/packages/sheets-ui/src/services/clipboard/copy-content-cache.ts b/packages/sheets-ui/src/services/clipboard/copy-content-cache.ts index caa489bd02..218424a541 100644 --- a/packages/sheets-ui/src/services/clipboard/copy-content-cache.ts +++ b/packages/sheets-ui/src/services/clipboard/copy-content-cache.ts @@ -17,11 +17,10 @@ import type { Nullable, ObjectMatrix } from '@univerjs/core'; import type { IDiscreteRange } from '@univerjs/sheets'; import type { COPY_TYPE, ICellDataWithSpanInfo } from './type'; -import { generateRandomId, LRUMap } from '@univerjs/core'; +import { LRUMap } from '@univerjs/core'; import { BehaviorSubject } from 'rxjs'; const COPY_CONTENT_CACHE_LIMIT = 10; -const ID_LENGTH = 6; export interface ICopyContentCacheData { subUnitId: string; @@ -31,10 +30,6 @@ export interface ICopyContentCacheData { matrix: Nullable>; } -export function genId() { - return generateRandomId(ID_LENGTH); -} - export function extractId(html: string) { const match = html.match(/data-copy-id="([^\s]+)"/); diff --git a/packages/thread-comment/src/models/__tests__/thread-comment.model.spec.ts b/packages/thread-comment/src/models/__tests__/thread-comment.model.spec.ts index 1aef321ccd..33b30c555e 100644 --- a/packages/thread-comment/src/models/__tests__/thread-comment.model.spec.ts +++ b/packages/thread-comment/src/models/__tests__/thread-comment.model.spec.ts @@ -18,6 +18,7 @@ import type { IDocumentBody, Injector, IWorkbookData } from '@univerjs/core'; import type { IThreadComment } from '../../types/interfaces/i-thread-comment'; import type { CommentUpdate } from '../thread-comment.model'; import { + awaitTime, IUniverInstanceService, LifecycleService, LifecycleStages, @@ -134,8 +135,8 @@ describe('ThreadCommentModel', () => { expect(listComments).not.toHaveBeenCalled(); lifecycleService.stage = LifecycleStages.Rendered; - await new Promise((resolve) => setTimeout(resolve, 0)); - await new Promise((resolve) => setTimeout(resolve, 0)); + await awaitTime(0); + await awaitTime(0); subscription.unsubscribe(); diff --git a/packages/watermark/src/controllers/watermark.render.controller.spec.ts b/packages/watermark/src/controllers/watermark.render.controller.spec.ts index 56f9d77a8d..fb929bc1ce 100644 --- a/packages/watermark/src/controllers/watermark.render.controller.spec.ts +++ b/packages/watermark/src/controllers/watermark.render.controller.spec.ts @@ -14,9 +14,9 @@ * limitations under the License. */ +import { awaitTime } from '@univerjs/core'; import { IWatermarkTypeEnum, UNIVER_WATERMARK_STORAGE_KEY } from '@univerjs/engine-render'; import { Subject } from 'rxjs'; - import { describe, expect, it, vi } from 'vitest'; import { WatermarkRenderController } from './watermark.render.controller'; @@ -46,12 +46,6 @@ vi.mock('@univerjs/engine-render', async () => { }; }); -function waitNextTick() { - return new Promise((resolve) => { - setTimeout(resolve, 0); - }); -} - describe('WatermarkRenderController', () => { it('should init layer, load config and react to updates', async () => { layerInstances.length = 0; @@ -88,7 +82,7 @@ describe('WatermarkRenderController', () => { expect(scene.addLayer).toHaveBeenCalledTimes(1); expect(localStorageService.getItem).toHaveBeenCalledWith(UNIVER_WATERMARK_STORAGE_KEY); - await waitNextTick(); + await awaitTime(0); expect(updateWatermarkConfig).toHaveBeenCalledWith({ type: IWatermarkTypeEnum.Text, config: { text: { content: 'init' } }, @@ -142,7 +136,7 @@ describe('WatermarkRenderController', () => { ); expect(_controller).toBeDefined(); - await waitNextTick(); + await awaitTime(0); expect(updateWatermarkConfig).not.toHaveBeenCalled(); expect(makeDirty).not.toHaveBeenCalled(); });