mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-24 05:07:06 +08:00
refactor(editor): use lodash (#10657)
This commit is contained in:
@@ -57,7 +57,7 @@ import {
|
|||||||
type SerializedXYWH,
|
type SerializedXYWH,
|
||||||
Vec,
|
Vec,
|
||||||
} from '@blocksuite/global/gfx';
|
} from '@blocksuite/global/gfx';
|
||||||
import { assertType, DisposableGroup, nToLast } from '@blocksuite/global/utils';
|
import { assertType, DisposableGroup } from '@blocksuite/global/utils';
|
||||||
import {
|
import {
|
||||||
type BlockSnapshot,
|
type BlockSnapshot,
|
||||||
BlockSnapshotSchema,
|
BlockSnapshotSchema,
|
||||||
@@ -1168,13 +1168,13 @@ export class EdgelessClipboardController extends PageClipboard {
|
|||||||
const bGroups = b.groups as SurfaceGroupLikeModel[];
|
const bGroups = b.groups as SurfaceGroupLikeModel[];
|
||||||
|
|
||||||
let i = 1;
|
let i = 1;
|
||||||
let aGroup: GfxModel | undefined = nToLast(aGroups, i);
|
let aGroup: GfxModel | undefined = aGroups.at(-i);
|
||||||
let bGroup: GfxModel | undefined = nToLast(bGroups, i);
|
let bGroup: GfxModel | undefined = bGroups.at(-i);
|
||||||
|
|
||||||
while (aGroup === bGroup && aGroup) {
|
while (aGroup === bGroup && aGroup) {
|
||||||
++i;
|
++i;
|
||||||
aGroup = nToLast(aGroups, i);
|
aGroup = aGroups.at(-i);
|
||||||
bGroup = nToLast(bGroups, i);
|
bGroup = bGroups.at(-i);
|
||||||
}
|
}
|
||||||
|
|
||||||
aGroup = aGroup ?? a;
|
aGroup = aGroup ?? a;
|
||||||
|
|||||||
+12
-8
@@ -56,7 +56,7 @@ import {
|
|||||||
normalizeDegAngle,
|
normalizeDegAngle,
|
||||||
} from '@blocksuite/global/gfx';
|
} from '@blocksuite/global/gfx';
|
||||||
import type { Disposable } from '@blocksuite/global/utils';
|
import type { Disposable } from '@blocksuite/global/utils';
|
||||||
import { assertType, pickValues, Slot } from '@blocksuite/global/utils';
|
import { assertType, Slot } from '@blocksuite/global/utils';
|
||||||
import { css, html, nothing } from 'lit';
|
import { css, html, nothing } from 'lit';
|
||||||
import { state } from 'lit/decorators.js';
|
import { state } from 'lit/decorators.js';
|
||||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||||
@@ -1310,13 +1310,17 @@ export class EdgelessSelectedRectWidget extends WidgetComponent<
|
|||||||
gfx.viewport.viewportUpdated.on(this._updateOnViewportChange)
|
gfx.viewport.viewportUpdated.on(this._updateOnViewportChange)
|
||||||
);
|
);
|
||||||
|
|
||||||
pickValues(gfx.surface!, [
|
if (gfx.surface) {
|
||||||
'elementAdded',
|
_disposables.add(
|
||||||
'elementRemoved',
|
gfx.surface.elementAdded.on(this._updateOnElementChange)
|
||||||
'elementUpdated',
|
);
|
||||||
]).forEach(slot => {
|
_disposables.add(
|
||||||
_disposables.add(slot.on(this._updateOnElementChange));
|
gfx.surface.elementRemoved.on(this._updateOnElementChange)
|
||||||
});
|
);
|
||||||
|
_disposables.add(
|
||||||
|
gfx.surface.elementUpdated.on(this._updateOnElementChange)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
_disposables.add(
|
_disposables.add(
|
||||||
this.doc.slots.blockUpdated.on(this._updateOnElementChange)
|
this.doc.slots.blockUpdated.on(this._updateOnElementChange)
|
||||||
|
|||||||
+6
-14
@@ -1,5 +1,3 @@
|
|||||||
import { keys } from '@blocksuite/global/utils';
|
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
Template,
|
Template,
|
||||||
TemplateCategory,
|
TemplateCategory,
|
||||||
@@ -40,7 +38,7 @@ const flat = <T>(arr: T[][]) =>
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
export const builtInTemplates = {
|
export const builtInTemplates = {
|
||||||
list: async (category: string) => {
|
list: async (category: string): Promise<Template[]> => {
|
||||||
const extendTemplates = flat(
|
const extendTemplates = flat(
|
||||||
await Promise.all(extendTemplate.map(manager => manager.list(category)))
|
await Promise.all(extendTemplate.map(manager => manager.list(category)))
|
||||||
);
|
);
|
||||||
@@ -52,15 +50,12 @@ export const builtInTemplates = {
|
|||||||
const result: Template[] =
|
const result: Template[] =
|
||||||
cate.templates instanceof Function
|
cate.templates instanceof Function
|
||||||
? await cate.templates()
|
? await cate.templates()
|
||||||
: await Promise.all(
|
: await Promise.all(Object.values(cate.templates));
|
||||||
// @ts-expect-error FIXME: ts error
|
|
||||||
keys(cate.templates).map(key => cate.templates[key]())
|
|
||||||
);
|
|
||||||
|
|
||||||
return result.concat(extendTemplates);
|
return result.concat(extendTemplates);
|
||||||
},
|
},
|
||||||
|
|
||||||
categories: async () => {
|
categories: async (): Promise<string[]> => {
|
||||||
const extendCates = flat(
|
const extendCates = flat(
|
||||||
await Promise.all(extendTemplate.map(manager => manager.categories()))
|
await Promise.all(extendTemplate.map(manager => manager.categories()))
|
||||||
);
|
);
|
||||||
@@ -69,7 +64,7 @@ export const builtInTemplates = {
|
|||||||
return templates.map(cate => cate.name).concat(extendCates);
|
return templates.map(cate => cate.name).concat(extendCates);
|
||||||
},
|
},
|
||||||
|
|
||||||
search: async (keyword: string, cateName?: string) => {
|
search: async (keyword: string, cateName?: string): Promise<Template[]> => {
|
||||||
const candidates: Template[] = flat(
|
const candidates: Template[] = flat(
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
extendTemplate.map(manager => manager.search(keyword, cateName))
|
extendTemplate.map(manager => manager.search(keyword, cateName))
|
||||||
@@ -86,18 +81,15 @@ export const builtInTemplates = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (categroy.templates instanceof Function) {
|
if (categroy.templates instanceof Function) {
|
||||||
return;
|
return categroy.templates();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
keys(categroy.templates).map(async name => {
|
Object.entries(categroy.templates).map(async ([name, template]) => {
|
||||||
if (
|
if (
|
||||||
lcs(keyword, (name as string).toLocaleLowerCase()) ===
|
lcs(keyword, (name as string).toLocaleLowerCase()) ===
|
||||||
keyword.length
|
keyword.length
|
||||||
) {
|
) {
|
||||||
// @ts-expect-error FIXME: ts error
|
|
||||||
const template = await categroy.templates[name]();
|
|
||||||
|
|
||||||
candidates.push(template);
|
candidates.push(template);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { PointerEventState } from '@blocksuite/block-std';
|
import type { PointerEventState } from '@blocksuite/block-std';
|
||||||
import type { GfxElementModelView } from '@blocksuite/block-std/gfx';
|
import type { GfxElementModelView } from '@blocksuite/block-std/gfx';
|
||||||
import { Bound } from '@blocksuite/global/gfx';
|
import { Bound } from '@blocksuite/global/gfx';
|
||||||
import { last } from '@blocksuite/global/utils';
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
import { DefaultModeDragType, DefaultToolExt } from './ext.js';
|
import { DefaultModeDragType, DefaultToolExt } from './ext.js';
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import {
|
|||||||
type MindmapRoot,
|
type MindmapRoot,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { Bound } from '@blocksuite/global/gfx';
|
import { Bound } from '@blocksuite/global/gfx';
|
||||||
import { last } from '@blocksuite/global/utils';
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
const isOnEdge = (node: MindmapNode, direction: 'tail' | 'head') => {
|
const isOnEdge = (node: MindmapNode, direction: 'tail' | 'head') => {
|
||||||
let current = node;
|
let current = node;
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ import {
|
|||||||
toRadian,
|
toRadian,
|
||||||
Vec,
|
Vec,
|
||||||
} from '@blocksuite/global/gfx';
|
} from '@blocksuite/global/gfx';
|
||||||
import { last } from '@blocksuite/global/utils';
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
export class MindMapIndicatorOverlay extends Overlay {
|
export class MindMapIndicatorOverlay extends Overlay {
|
||||||
static INDICATOR_SIZE = [48, 22];
|
static INDICATOR_SIZE = [48, 22];
|
||||||
|
|||||||
@@ -43,9 +43,10 @@ import {
|
|||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import type { IVec } from '@blocksuite/global/gfx';
|
import type { IVec } from '@blocksuite/global/gfx';
|
||||||
import { Bound, getCommonBoundWithRotation, Vec } from '@blocksuite/global/gfx';
|
import { Bound, getCommonBoundWithRotation, Vec } from '@blocksuite/global/gfx';
|
||||||
import { DisposableGroup, last, noop } from '@blocksuite/global/utils';
|
import { DisposableGroup, noop } from '@blocksuite/global/utils';
|
||||||
import { effect } from '@preact/signals-core';
|
import { effect } from '@preact/signals-core';
|
||||||
import clamp from 'lodash-es/clamp';
|
import clamp from 'lodash-es/clamp';
|
||||||
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
||||||
import { prepareCloneData } from '../utils/clone-utils.js';
|
import { prepareCloneData } from '../utils/clone-utils.js';
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import {
|
|||||||
type SerializedElement,
|
type SerializedElement,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { getCommonBoundWithRotation } from '@blocksuite/global/gfx';
|
import { getCommonBoundWithRotation } from '@blocksuite/global/gfx';
|
||||||
import { groupBy } from '@blocksuite/global/utils';
|
|
||||||
import { type BlockSnapshot, BlockSnapshotSchema } from '@blocksuite/store';
|
import { type BlockSnapshot, BlockSnapshotSchema } from '@blocksuite/store';
|
||||||
|
import groupBy from 'lodash-es/groupBy';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
||||||
import { getSortedCloneElements, prepareCloneData } from './clone-utils.js';
|
import { getSortedCloneElements, prepareCloneData } from './clone-utils.js';
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ import {
|
|||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { WithDisposable } from '@blocksuite/global/utils';
|
||||||
import { html, LitElement, nothing } from 'lit';
|
import { html, LitElement, nothing } from 'lit';
|
||||||
import { property, query } from 'lit/decorators.js';
|
import { property, query } from 'lit/decorators.js';
|
||||||
import { when } from 'lit/directives/when.js';
|
import { when } from 'lit/directives/when.js';
|
||||||
|
import countBy from 'lodash-es/countBy';
|
||||||
|
import maxBy from 'lodash-es/maxBy';
|
||||||
|
|
||||||
import type { LineWidthEvent } from '../../edgeless/components/panel/line-width-panel.js';
|
import type { LineWidthEvent } from '../../edgeless/components/panel/line-width-panel.js';
|
||||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { WithDisposable } from '@blocksuite/global/utils';
|
||||||
import {
|
import {
|
||||||
AddTextIcon,
|
AddTextIcon,
|
||||||
ConnectorCIcon,
|
ConnectorCIcon,
|
||||||
@@ -51,6 +51,8 @@ import { join } from 'lit/directives/join.js';
|
|||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
import { when } from 'lit/directives/when.js';
|
import { when } from 'lit/directives/when.js';
|
||||||
|
import countBy from 'lodash-es/countBy';
|
||||||
|
import maxBy from 'lodash-es/maxBy';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type LineStyleEvent,
|
type LineStyleEvent,
|
||||||
|
|||||||
@@ -23,12 +23,14 @@ import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
|||||||
import { matchModels } from '@blocksuite/affine-shared/utils';
|
import { matchModels } from '@blocksuite/affine-shared/utils';
|
||||||
import { GfxExtensionIdentifier } from '@blocksuite/block-std/gfx';
|
import { GfxExtensionIdentifier } from '@blocksuite/block-std/gfx';
|
||||||
import { deserializeXYWH, serializeXYWH } from '@blocksuite/global/gfx';
|
import { deserializeXYWH, serializeXYWH } from '@blocksuite/global/gfx';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { WithDisposable } from '@blocksuite/global/utils';
|
||||||
import { EditIcon, PageIcon, UngroupIcon } from '@blocksuite/icons/lit';
|
import { EditIcon, PageIcon, UngroupIcon } from '@blocksuite/icons/lit';
|
||||||
import { html, LitElement, nothing } from 'lit';
|
import { html, LitElement, nothing } from 'lit';
|
||||||
import { property, query } from 'lit/decorators.js';
|
import { property, query } from 'lit/decorators.js';
|
||||||
import { join } from 'lit/directives/join.js';
|
import { join } from 'lit/directives/join.js';
|
||||||
import { when } from 'lit/directives/when.js';
|
import { when } from 'lit/directives/when.js';
|
||||||
|
import countBy from 'lodash-es/countBy';
|
||||||
|
import maxBy from 'lodash-es/maxBy';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||||
import { mountFrameTitleEditor } from '../../edgeless/utils/text.js';
|
import { mountFrameTitleEditor } from '../../edgeless/utils/text.js';
|
||||||
|
|||||||
@@ -11,12 +11,14 @@ import type {
|
|||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { LayoutType, MindmapStyle } from '@blocksuite/affine-model';
|
import { LayoutType, MindmapStyle } from '@blocksuite/affine-model';
|
||||||
import { EditPropsStore } from '@blocksuite/affine-shared/services';
|
import { EditPropsStore } from '@blocksuite/affine-shared/services';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { WithDisposable } from '@blocksuite/global/utils';
|
||||||
import { RadiantIcon, RightLayoutIcon, StyleIcon } from '@blocksuite/icons/lit';
|
import { RadiantIcon, RightLayoutIcon, StyleIcon } from '@blocksuite/icons/lit';
|
||||||
import { css, html, LitElement, nothing, type TemplateResult } from 'lit';
|
import { css, html, LitElement, nothing, type TemplateResult } from 'lit';
|
||||||
import { property, state } from 'lit/decorators.js';
|
import { property, state } from 'lit/decorators.js';
|
||||||
import { join } from 'lit/directives/join.js';
|
import { join } from 'lit/directives/join.js';
|
||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
|
import countBy from 'lodash-es/countBy';
|
||||||
|
import maxBy from 'lodash-es/maxBy';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||||
import { SmallArrowDownIcon } from './icons.js';
|
import { SmallArrowDownIcon } from './icons.js';
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import {
|
|||||||
ThemeProvider,
|
ThemeProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { Bound } from '@blocksuite/global/gfx';
|
import { Bound } from '@blocksuite/global/gfx';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { WithDisposable } from '@blocksuite/global/utils';
|
||||||
import {
|
import {
|
||||||
AutoHeightIcon,
|
AutoHeightIcon,
|
||||||
CornerIcon,
|
CornerIcon,
|
||||||
@@ -46,6 +46,8 @@ import { property, query } from 'lit/decorators.js';
|
|||||||
import { join } from 'lit/directives/join.js';
|
import { join } from 'lit/directives/join.js';
|
||||||
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
|
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
|
||||||
import { when } from 'lit/directives/when.js';
|
import { when } from 'lit/directives/when.js';
|
||||||
|
import countBy from 'lodash-es/countBy';
|
||||||
|
import maxBy from 'lodash-es/maxBy';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type LineStyleEvent,
|
type LineStyleEvent,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import {
|
|||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { WithDisposable } from '@blocksuite/global/utils';
|
||||||
import {
|
import {
|
||||||
AddTextIcon,
|
AddTextIcon,
|
||||||
ShapeIcon,
|
ShapeIcon,
|
||||||
@@ -43,7 +43,9 @@ import { choose } from 'lit/directives/choose.js';
|
|||||||
import { join } from 'lit/directives/join.js';
|
import { join } from 'lit/directives/join.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
import { when } from 'lit/directives/when.js';
|
import { when } from 'lit/directives/when.js';
|
||||||
import { isEqual } from 'lodash-es';
|
import countBy from 'lodash-es/countBy';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
|
import maxBy from 'lodash-es/maxBy';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type LineStyleEvent,
|
type LineStyleEvent,
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import {
|
|||||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
||||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||||
import { Bound } from '@blocksuite/global/gfx';
|
import { Bound } from '@blocksuite/global/gfx';
|
||||||
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
|
import { WithDisposable } from '@blocksuite/global/utils';
|
||||||
import {
|
import {
|
||||||
TextAlignCenterIcon,
|
TextAlignCenterIcon,
|
||||||
TextAlignLeftIcon,
|
TextAlignLeftIcon,
|
||||||
@@ -43,6 +43,8 @@ import { property, query } from 'lit/decorators.js';
|
|||||||
import { choose } from 'lit/directives/choose.js';
|
import { choose } from 'lit/directives/choose.js';
|
||||||
import { join } from 'lit/directives/join.js';
|
import { join } from 'lit/directives/join.js';
|
||||||
import { when } from 'lit/directives/when.js';
|
import { when } from 'lit/directives/when.js';
|
||||||
|
import countBy from 'lodash-es/countBy';
|
||||||
|
import maxBy from 'lodash-es/maxBy';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||||
import { SmallArrowDownIcon } from './icons.js';
|
import { SmallArrowDownIcon } from './icons.js';
|
||||||
|
|||||||
@@ -31,11 +31,11 @@ import { requestConnectedFrame } from '@blocksuite/affine-shared/utils';
|
|||||||
import { WidgetComponent } from '@blocksuite/block-std';
|
import { WidgetComponent } from '@blocksuite/block-std';
|
||||||
import type { GfxModel } from '@blocksuite/block-std/gfx';
|
import type { GfxModel } from '@blocksuite/block-std/gfx';
|
||||||
import { clamp, getCommonBoundWithRotation } from '@blocksuite/global/gfx';
|
import { clamp, getCommonBoundWithRotation } from '@blocksuite/global/gfx';
|
||||||
import { atLeastNMatches, groupBy, pickValues } from '@blocksuite/global/utils';
|
|
||||||
import { ConnectorCIcon } from '@blocksuite/icons/lit';
|
import { ConnectorCIcon } from '@blocksuite/icons/lit';
|
||||||
import { css, html, nothing, type TemplateResult, unsafeCSS } from 'lit';
|
import { css, html, nothing, type TemplateResult, unsafeCSS } from 'lit';
|
||||||
import { property, state } from 'lit/decorators.js';
|
import { property, state } from 'lit/decorators.js';
|
||||||
import { join } from 'lit/directives/join.js';
|
import { join } from 'lit/directives/join.js';
|
||||||
|
import groupBy from 'lodash-es/groupBy';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||||
import {
|
import {
|
||||||
@@ -270,11 +270,8 @@ export class EdgelessElementToolbarWidget extends WidgetComponent<
|
|||||||
edgelessText,
|
edgelessText,
|
||||||
mindmap: mindmaps,
|
mindmap: mindmaps,
|
||||||
} = groupedSelected;
|
} = groupedSelected;
|
||||||
const selectedAtLeastTwoTypes = atLeastNMatches(
|
const selectedAtLeastTwoTypes =
|
||||||
Object.values(groupedSelected),
|
Object.values(groupedSelected).filter(e => !!e.length).length >= 2;
|
||||||
e => !!e.length,
|
|
||||||
2
|
|
||||||
);
|
|
||||||
|
|
||||||
const quickConnectButton =
|
const quickConnectButton =
|
||||||
selectedElements.length === 1 && !connector?.length
|
selectedElements.length === 1 && !connector?.length
|
||||||
@@ -385,10 +382,16 @@ export class EdgelessElementToolbarWidget extends WidgetComponent<
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
pickValues(this.edgeless.service.surface, [
|
_disposables.add(
|
||||||
'elementAdded',
|
this.edgeless.service.surface.elementAdded.on(
|
||||||
'elementUpdated',
|
this._updateOnSelectedChange
|
||||||
]).forEach(slot => _disposables.add(slot.on(this._updateOnSelectedChange)));
|
)
|
||||||
|
);
|
||||||
|
_disposables.add(
|
||||||
|
this.edgeless.service.surface.elementUpdated.on(
|
||||||
|
this._updateOnSelectedChange
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
_disposables.add(
|
_disposables.add(
|
||||||
this.doc.slots.blockUpdated.on(this._updateOnSelectedChange)
|
this.doc.slots.blockUpdated.on(this._updateOnSelectedChange)
|
||||||
|
|||||||
@@ -25,15 +25,13 @@
|
|||||||
"@lit/context": "^1.1.2",
|
"@lit/context": "^1.1.2",
|
||||||
"@preact/signals-core": "^1.8.0",
|
"@preact/signals-core": "^1.8.0",
|
||||||
"@toeverything/theme": "^1.1.12",
|
"@toeverything/theme": "^1.1.12",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
"fractional-indexing": "^3.2.0",
|
"fractional-indexing": "^3.2.0",
|
||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
"lodash.chunk": "^4.2.0",
|
"lodash-es": "^4.17.21",
|
||||||
"nanoid": "^5.0.7",
|
"nanoid": "^5.0.7",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
|
||||||
"@types/lodash.chunk": "^4.2.9"
|
|
||||||
},
|
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./src/index.ts",
|
".": "./src/index.ts",
|
||||||
"./effects": "./src/effects.ts"
|
"./effects": "./src/effects.ts"
|
||||||
|
|||||||
@@ -23,17 +23,17 @@
|
|||||||
"@lit/context": "^1.1.2",
|
"@lit/context": "^1.1.2",
|
||||||
"@preact/signals-core": "^1.8.0",
|
"@preact/signals-core": "^1.8.0",
|
||||||
"@toeverything/theme": "^1.1.12",
|
"@toeverything/theme": "^1.1.12",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
"fractional-indexing": "^3.2.0",
|
"fractional-indexing": "^3.2.0",
|
||||||
"html2canvas": "^1.4.1",
|
"html2canvas": "^1.4.1",
|
||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
"lodash.chunk": "^4.2.0",
|
"lodash-es": "^4.17.21",
|
||||||
"nanoid": "^5.0.7",
|
"nanoid": "^5.0.7",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"yjs": "^13.6.21",
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash.chunk": "^4.2.9",
|
|
||||||
"vitest": "3.0.7"
|
"vitest": "3.0.7"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
type GfxModel,
|
type GfxModel,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { Bound } from '@blocksuite/global/gfx';
|
import { Bound } from '@blocksuite/global/gfx';
|
||||||
import chunk from 'lodash.chunk';
|
import chunk from 'lodash-es/chunk';
|
||||||
|
|
||||||
const ALIGN_HEIGHT = 200;
|
const ALIGN_HEIGHT = 200;
|
||||||
const ALIGN_PADDING = 20;
|
const ALIGN_PADDING = 20;
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ import {
|
|||||||
toRadian,
|
toRadian,
|
||||||
Vec,
|
Vec,
|
||||||
} from '@blocksuite/global/gfx';
|
} from '@blocksuite/global/gfx';
|
||||||
import { assertType, last } from '@blocksuite/global/utils';
|
import { assertType } from '@blocksuite/global/utils';
|
||||||
import { effect } from '@preact/signals-core';
|
import { effect } from '@preact/signals-core';
|
||||||
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
import { Overlay } from '../renderer/overlay.js';
|
import { Overlay } from '../renderer/overlay.js';
|
||||||
import { AStarRunner } from '../utils/a-star.js';
|
import { AStarRunner } from '../utils/a-star.js';
|
||||||
@@ -602,7 +603,7 @@ function mergePath(points: IVec[] | IVec3[]) {
|
|||||||
continue;
|
continue;
|
||||||
result.push([cur[0], cur[1]]);
|
result.push([cur[0], cur[1]]);
|
||||||
}
|
}
|
||||||
result.push(last(points) as IVec);
|
result.push(last(points as IVec[]) as IVec);
|
||||||
for (let i = 0; i < result.length - 1; i++) {
|
for (let i = 0; i < result.length - 1; i++) {
|
||||||
const cur = result[i];
|
const cur = result[i];
|
||||||
const next = result[i + 1];
|
const next = result[i + 1];
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import type {
|
|||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import type { IBound } from '@blocksuite/global/gfx';
|
import type { IBound } from '@blocksuite/global/gfx';
|
||||||
import { getBoundWithRotation, intersects } from '@blocksuite/global/gfx';
|
import { getBoundWithRotation, intersects } from '@blocksuite/global/gfx';
|
||||||
import { DisposableGroup, last, Slot } from '@blocksuite/global/utils';
|
import { DisposableGroup, Slot } from '@blocksuite/global/utils';
|
||||||
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
import type { SurfaceElementModel } from '../element-model/base.js';
|
import type { SurfaceElementModel } from '../element-model/base.js';
|
||||||
import { RoughCanvas } from '../utils/rough/canvas.js';
|
import { RoughCanvas } from '../utils/rough/canvas.js';
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import {
|
|||||||
type SurfaceBlockModel,
|
type SurfaceBlockModel,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import type { IVec } from '@blocksuite/global/gfx';
|
import type { IVec } from '@blocksuite/global/gfx';
|
||||||
import { assertType, isEqual, last } from '@blocksuite/global/utils';
|
import { assertType } from '@blocksuite/global/utils';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
|
import last from 'lodash-es/last';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { fitContent } from '../../renderer/elements/shape/utils.js';
|
import { fitContent } from '../../renderer/elements/shape/utils.js';
|
||||||
|
|||||||
@@ -24,8 +24,10 @@
|
|||||||
"@lit/context": "^1.1.2",
|
"@lit/context": "^1.1.2",
|
||||||
"@preact/signals-core": "^1.8.0",
|
"@preact/signals-core": "^1.8.0",
|
||||||
"@toeverything/theme": "^1.1.12",
|
"@toeverything/theme": "^1.1.12",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
"date-fns": "^4.0.0",
|
"date-fns": "^4.0.0",
|
||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
"yjs": "^13.6.21",
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { ShadowlessElement } from '@blocksuite/block-std';
|
import { ShadowlessElement } from '@blocksuite/block-std';
|
||||||
import { isEqual } from '@blocksuite/global/utils';
|
|
||||||
import { type Text } from '@blocksuite/store';
|
import { type Text } from '@blocksuite/store';
|
||||||
import { css, html } from 'lit';
|
import { css, html } from 'lit';
|
||||||
import { state } from 'lit/decorators.js';
|
import { state } from 'lit/decorators.js';
|
||||||
import { createRef, ref } from 'lit/directives/ref.js';
|
import { createRef, ref } from 'lit/directives/ref.js';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { t } from '../../../../core/index.js';
|
import { t } from '../../../../core/index.js';
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
"@blocksuite/inline": "workspace:*",
|
"@blocksuite/inline": "workspace:*",
|
||||||
"@blocksuite/store": "workspace:*",
|
"@blocksuite/store": "workspace:*",
|
||||||
"@toeverything/theme": "^1.1.12",
|
"@toeverything/theme": "^1.1.12",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
"fractional-indexing": "^3.2.0",
|
"fractional-indexing": "^3.2.0",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
"yjs": "^13.6.21",
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {
|
|||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import type { IVec, PointLocation } from '@blocksuite/global/gfx';
|
import type { IVec, PointLocation } from '@blocksuite/global/gfx';
|
||||||
import { Bound, linePolygonIntersects } from '@blocksuite/global/gfx';
|
import { Bound, linePolygonIntersects } from '@blocksuite/global/gfx';
|
||||||
import { keys } from '@blocksuite/global/utils';
|
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
type GroupElementProps = BaseElementProps & {
|
type GroupElementProps = BaseElementProps & {
|
||||||
@@ -44,7 +43,7 @@ export class GroupElementModel extends GfxGroupLikeElementModel<GroupElementProp
|
|||||||
if (props.children && !(props.children instanceof Y.Map)) {
|
if (props.children && !(props.children instanceof Y.Map)) {
|
||||||
const children = new Y.Map() as Y.Map<boolean>;
|
const children = new Y.Map() as Y.Map<boolean>;
|
||||||
|
|
||||||
keys(props.children).forEach(key => {
|
Object.keys(props.children).forEach(key => {
|
||||||
children.set(key as string, true);
|
children.set(key as string, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,10 @@ import {
|
|||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import type { Bound, SerializedXYWH, XYWH } from '@blocksuite/global/gfx';
|
import type { Bound, SerializedXYWH, XYWH } from '@blocksuite/global/gfx';
|
||||||
import { deserializeXYWH } from '@blocksuite/global/gfx';
|
import { deserializeXYWH } from '@blocksuite/global/gfx';
|
||||||
import { assertType, keys, last, noop, pick } from '@blocksuite/global/utils';
|
import { assertType, noop } from '@blocksuite/global/utils';
|
||||||
import { generateKeyBetween } from 'fractional-indexing';
|
import { generateKeyBetween } from 'fractional-indexing';
|
||||||
|
import last from 'lodash-es/last';
|
||||||
|
import pick from 'lodash-es/pick';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@@ -182,11 +184,11 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
|
|||||||
) {
|
) {
|
||||||
const children: Y.Map<NodeDetail> = new Y.Map();
|
const children: Y.Map<NodeDetail> = new Y.Map();
|
||||||
|
|
||||||
keys(props.children).forEach(key => {
|
Object.entries(props.children).forEach(([key, value]) => {
|
||||||
const detail = pick<Record<string, unknown>, keyof NodeDetail>(
|
const detail = pick<Record<string, unknown>, keyof NodeDetail>(value, [
|
||||||
props.children![key],
|
'index',
|
||||||
['index', 'parent']
|
'parent',
|
||||||
);
|
]);
|
||||||
children.set(key as string, detail as NodeDetail);
|
children.set(key as string, detail as NodeDetail);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { isEqual, last } from '@blocksuite/global/utils';
|
import isEqual from 'lodash-es/isEqual';
|
||||||
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
import { ConnectorMode } from '../../consts/connector.js';
|
import { ConnectorMode } from '../../consts/connector.js';
|
||||||
import { MindmapStyle } from '../../consts/mindmap.js';
|
import { MindmapStyle } from '../../consts/mindmap.js';
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
import {
|
|
||||||
atLeastNMatches,
|
|
||||||
countBy,
|
|
||||||
groupBy,
|
|
||||||
maxBy,
|
|
||||||
} from '@blocksuite/global/utils';
|
|
||||||
import { describe, expect, it } from 'vitest';
|
|
||||||
|
|
||||||
describe('countBy', () => {
|
|
||||||
it('basic', () => {
|
|
||||||
const items = [
|
|
||||||
{ name: 'a', classroom: 'c1' },
|
|
||||||
{ name: 'b', classroom: 'c2' },
|
|
||||||
{ name: 'a', classroom: 'c2' },
|
|
||||||
];
|
|
||||||
const counted = countBy(items, i => i.name);
|
|
||||||
expect(counted).toEqual({ a: 2, b: 1 });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('empty items', () => {
|
|
||||||
const counted = countBy([], i => i);
|
|
||||||
expect(Object.keys(counted).length).toBe(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('maxBy', () => {
|
|
||||||
it('basic', () => {
|
|
||||||
const items = [{ n: 1 }, { n: 2 }];
|
|
||||||
const max = maxBy(items, i => i.n);
|
|
||||||
expect(max).toBe(items[1]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('empty items', () => {
|
|
||||||
expect(maxBy([], i => i)).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('atLeastNMatches', () => {
|
|
||||||
it('basic', () => {
|
|
||||||
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
||||||
const isEven = (num: number): boolean => num % 2 === 0;
|
|
||||||
const isGreaterThan5 = (num: number): boolean => num > 5;
|
|
||||||
const isNegative = (num: number): boolean => num < 0;
|
|
||||||
|
|
||||||
expect(atLeastNMatches(arr, isEven, 3)).toBe(true);
|
|
||||||
expect(atLeastNMatches(arr, isGreaterThan5, 5)).toBe(false);
|
|
||||||
expect(atLeastNMatches(arr, isNegative, 1)).toBe(false);
|
|
||||||
|
|
||||||
const strArr = ['apple', 'banana', 'orange', 'kiwi', 'mango'];
|
|
||||||
const startsWithA = (str: string): boolean => str[0].toLowerCase() === 'a';
|
|
||||||
const longerThan5 = (str: string): boolean => str.length > 5;
|
|
||||||
|
|
||||||
expect(atLeastNMatches(strArr, startsWithA, 1)).toBe(true);
|
|
||||||
expect(atLeastNMatches(strArr, longerThan5, 3)).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('groupBy', () => {
|
|
||||||
it('basic', () => {
|
|
||||||
const students = [
|
|
||||||
{ name: 'Alice', age: 25 },
|
|
||||||
{ name: 'Bob', age: 23 },
|
|
||||||
{ name: 'Cathy', age: 25 },
|
|
||||||
{ name: 'David', age: 23 },
|
|
||||||
];
|
|
||||||
|
|
||||||
const groupedByAge = groupBy(students, student => student.age.toString());
|
|
||||||
const expectedGroupedByAge = {
|
|
||||||
'23': [
|
|
||||||
{ name: 'Bob', age: 23 },
|
|
||||||
{ name: 'David', age: 23 },
|
|
||||||
],
|
|
||||||
'25': [
|
|
||||||
{ name: 'Alice', age: 25 },
|
|
||||||
{ name: 'Cathy', age: 25 },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
expect(groupedByAge).toMatchObject(expectedGroupedByAge);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('empty', () => {
|
|
||||||
const emptyArray: string[] = [];
|
|
||||||
const groupedEmptyArray = groupBy(emptyArray, item => item);
|
|
||||||
expect(Object.keys(groupedEmptyArray).length).toBe(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -2,9 +2,9 @@ import {
|
|||||||
createIdentifier,
|
createIdentifier,
|
||||||
type ServiceIdentifier,
|
type ServiceIdentifier,
|
||||||
} from '@blocksuite/global/di';
|
} from '@blocksuite/global/di';
|
||||||
import { isEqual } from '@blocksuite/global/utils';
|
|
||||||
import type { DeltaInsert } from '@blocksuite/inline';
|
import type { DeltaInsert } from '@blocksuite/inline';
|
||||||
import type { ExtensionType } from '@blocksuite/store';
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
|
|
||||||
import type { AffineTextAttributes } from '../../types/index.js';
|
import type { AffineTextAttributes } from '../../types/index.js';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { ReferenceParams } from '@blocksuite/affine-model';
|
import type { ReferenceParams } from '@blocksuite/affine-model';
|
||||||
import { isEqual } from '@blocksuite/global/utils';
|
|
||||||
import type { DeltaInsert } from '@blocksuite/inline';
|
import type { DeltaInsert } from '@blocksuite/inline';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
|
|
||||||
const mergeDeltas = (
|
const mergeDeltas = (
|
||||||
acc: DeltaInsert[],
|
acc: DeltaInsert[],
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ import {
|
|||||||
Rect,
|
Rect,
|
||||||
type SerializedXYWH,
|
type SerializedXYWH,
|
||||||
} from '@blocksuite/global/gfx';
|
} from '@blocksuite/global/gfx';
|
||||||
import { assertType, groupBy, last } from '@blocksuite/global/utils';
|
import { assertType } from '@blocksuite/global/utils';
|
||||||
import {
|
import {
|
||||||
type BlockModel,
|
type BlockModel,
|
||||||
type BlockSnapshot,
|
type BlockSnapshot,
|
||||||
@@ -63,6 +63,8 @@ import {
|
|||||||
type SliceSnapshot,
|
type SliceSnapshot,
|
||||||
toDraftModel,
|
toDraftModel,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
|
import groupBy from 'lodash-es/groupBy';
|
||||||
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
import type { AffineDragHandleWidget } from '../drag-handle.js';
|
import type { AffineDragHandleWidget } from '../drag-handle.js';
|
||||||
import { PreviewHelper } from '../helpers/preview-helper.js';
|
import { PreviewHelper } from '../helpers/preview-helper.js';
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
GfxControllerIdentifier,
|
GfxControllerIdentifier,
|
||||||
type GfxModel,
|
type GfxModel,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { pickValues } from '@blocksuite/global/utils';
|
|
||||||
import { MultiCursorDuotoneIcon } from '@blocksuite/icons/lit';
|
import { MultiCursorDuotoneIcon } from '@blocksuite/icons/lit';
|
||||||
import type { UserInfo } from '@blocksuite/store';
|
import type { UserInfo } from '@blocksuite/store';
|
||||||
import { css, html, nothing } from 'lit';
|
import { css, html, nothing } from 'lit';
|
||||||
@@ -183,13 +182,17 @@ export class EdgelessRemoteSelectionWidget extends WidgetComponent<RootBlockMode
|
|||||||
|
|
||||||
const { _disposables, doc } = this;
|
const { _disposables, doc } = this;
|
||||||
|
|
||||||
pickValues(this.surface!, [
|
if (this.surface) {
|
||||||
'elementAdded',
|
_disposables.add(
|
||||||
'elementRemoved',
|
this.surface.elementAdded.on(this._updateOnElementChange)
|
||||||
'elementUpdated',
|
);
|
||||||
]).forEach(slot => {
|
_disposables.add(
|
||||||
_disposables.add(slot.on(this._updateOnElementChange));
|
this.surface.elementRemoved.on(this._updateOnElementChange)
|
||||||
});
|
);
|
||||||
|
_disposables.add(
|
||||||
|
this.surface.elementUpdated.on(this._updateOnElementChange)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
_disposables.add(doc.slots.blockUpdated.on(this._updateOnElementChange));
|
_disposables.add(doc.slots.blockUpdated.on(this._updateOnElementChange));
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import {
|
|||||||
getCommonBoundWithRotation,
|
getCommonBoundWithRotation,
|
||||||
type IBound,
|
type IBound,
|
||||||
} from '@blocksuite/global/gfx';
|
} from '@blocksuite/global/gfx';
|
||||||
import { assertType, DisposableGroup, last } from '@blocksuite/global/utils';
|
import { assertType, DisposableGroup } from '@blocksuite/global/utils';
|
||||||
import type { BlockModel } from '@blocksuite/store';
|
import type { BlockModel } from '@blocksuite/store';
|
||||||
import { Signal } from '@preact/signals-core';
|
import { Signal } from '@preact/signals-core';
|
||||||
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
import { LifeCycleWatcher } from '../extension/lifecycle-watcher.js';
|
import { LifeCycleWatcher } from '../extension/lifecycle-watcher.js';
|
||||||
import type { BlockStdScope } from '../scope/block-std-scope.js';
|
import type { BlockStdScope } from '../scope/block-std-scope.js';
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
import { Bound } from '@blocksuite/global/gfx';
|
import { Bound } from '@blocksuite/global/gfx';
|
||||||
import {
|
import { assertType, DisposableGroup, Slot } from '@blocksuite/global/utils';
|
||||||
assertType,
|
|
||||||
DisposableGroup,
|
|
||||||
last,
|
|
||||||
Slot,
|
|
||||||
} from '@blocksuite/global/utils';
|
|
||||||
import type { Store } from '@blocksuite/store';
|
import type { Store } from '@blocksuite/store';
|
||||||
import { generateKeyBetween } from 'fractional-indexing';
|
import { generateKeyBetween } from 'fractional-indexing';
|
||||||
|
import last from 'lodash-es/last';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
compare,
|
compare,
|
||||||
@@ -162,7 +158,9 @@ export class LayerManager {
|
|||||||
if (curLayer) {
|
if (curLayer) {
|
||||||
curLayer.indexes = [
|
curLayer.indexes = [
|
||||||
getElementIndex(curLayer.elements[0]),
|
getElementIndex(curLayer.elements[0]),
|
||||||
getElementIndex(last(curLayer.elements)!),
|
getElementIndex(
|
||||||
|
last(curLayer.elements as GfxPrimitiveElementModel[])!
|
||||||
|
),
|
||||||
];
|
];
|
||||||
curLayer.zIndex = currentCSSZindex;
|
curLayer.zIndex = currentCSSZindex;
|
||||||
layers.push(curLayer as LayerManager['layers'][number]);
|
layers.push(curLayer as LayerManager['layers'][number]);
|
||||||
@@ -342,7 +340,10 @@ export class LayerManager {
|
|||||||
if (
|
if (
|
||||||
!last(this.layers) ||
|
!last(this.layers) ||
|
||||||
[SortOrder.AFTER, SortOrder.SAME].includes(
|
[SortOrder.AFTER, SortOrder.SAME].includes(
|
||||||
compare(target, last(last(this.layers)!.elements)!)
|
compare(
|
||||||
|
target,
|
||||||
|
last(last(this.layers)!.elements as GfxPrimitiveElementModel[])!
|
||||||
|
)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
const layer = last(this.layers);
|
const layer = last(this.layers);
|
||||||
@@ -364,7 +365,15 @@ export class LayerManager {
|
|||||||
const layer = layers[cur];
|
const layer = layers[cur];
|
||||||
const layerElements = layer.elements;
|
const layerElements = layer.elements;
|
||||||
|
|
||||||
if (isInRange([layerElements[0], last(layerElements)!], target)) {
|
if (
|
||||||
|
isInRange(
|
||||||
|
[
|
||||||
|
layerElements[0],
|
||||||
|
last(layerElements as GfxPrimitiveElementModel[])!,
|
||||||
|
],
|
||||||
|
target
|
||||||
|
)
|
||||||
|
) {
|
||||||
const insertIdx = layerElements.findIndex((_, idx) => {
|
const insertIdx = layerElements.findIndex((_, idx) => {
|
||||||
const pre = layerElements[idx - 1];
|
const pre = layerElements[idx - 1];
|
||||||
return (
|
return (
|
||||||
@@ -392,7 +401,13 @@ export class LayerManager {
|
|||||||
} else {
|
} else {
|
||||||
const nextLayer = layers[cur - 1];
|
const nextLayer = layers[cur - 1];
|
||||||
|
|
||||||
if (!nextLayer || compare(target, last(nextLayer.elements)!) >= 0) {
|
if (
|
||||||
|
!nextLayer ||
|
||||||
|
compare(
|
||||||
|
target,
|
||||||
|
last(nextLayer.elements as GfxPrimitiveElementModel[])!
|
||||||
|
) >= 0
|
||||||
|
) {
|
||||||
if (layer.type === type) {
|
if (layer.type === type) {
|
||||||
addToLayer(layer, target, 0);
|
addToLayer(layer, target, 0);
|
||||||
updateLayersZIndex(layers, cur);
|
updateLayersZIndex(layers, cur);
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ import {
|
|||||||
type SerializedXYWH,
|
type SerializedXYWH,
|
||||||
type XYWH,
|
type XYWH,
|
||||||
} from '@blocksuite/global/gfx';
|
} from '@blocksuite/global/gfx';
|
||||||
import { DisposableGroup, isEqual, Slot } from '@blocksuite/global/utils';
|
import { DisposableGroup, Slot } from '@blocksuite/global/utils';
|
||||||
import { createMutex } from 'lib0/mutex';
|
import { createMutex } from 'lib0/mutex';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -2,12 +2,8 @@ import {
|
|||||||
getCommonBoundWithRotation,
|
getCommonBoundWithRotation,
|
||||||
type IPoint,
|
type IPoint,
|
||||||
} from '@blocksuite/global/gfx';
|
} from '@blocksuite/global/gfx';
|
||||||
import {
|
import { assertType, DisposableGroup, Slot } from '@blocksuite/global/utils';
|
||||||
assertType,
|
import groupBy from 'lodash-es/groupBy';
|
||||||
DisposableGroup,
|
|
||||||
groupBy,
|
|
||||||
Slot,
|
|
||||||
} from '@blocksuite/global/utils';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BlockSelection,
|
BlockSelection,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { nToLast } from '@blocksuite/global/utils';
|
|
||||||
import type { Store } from '@blocksuite/store';
|
import type { Store } from '@blocksuite/store';
|
||||||
|
|
||||||
import type { GfxLocalElementModel } from '../gfx/index.js';
|
import type { GfxLocalElementModel } from '../gfx/index.js';
|
||||||
@@ -113,17 +112,17 @@ export function compare(
|
|||||||
| GfxModel
|
| GfxModel
|
||||||
| GfxGroupCompatibleInterface
|
| GfxGroupCompatibleInterface
|
||||||
| GfxLocalElementModel
|
| GfxLocalElementModel
|
||||||
| undefined = nToLast(aGroups, i);
|
| undefined = aGroups.at(-i);
|
||||||
let bGroup:
|
let bGroup:
|
||||||
| GfxModel
|
| GfxModel
|
||||||
| GfxGroupCompatibleInterface
|
| GfxGroupCompatibleInterface
|
||||||
| GfxLocalElementModel
|
| GfxLocalElementModel
|
||||||
| undefined = nToLast(bGroups, i);
|
| undefined = bGroups.at(-i);
|
||||||
|
|
||||||
while (aGroup === bGroup && aGroup) {
|
while (aGroup === bGroup && aGroup) {
|
||||||
++i;
|
++i;
|
||||||
aGroup = nToLast(aGroups, i);
|
aGroup = aGroups.at(-i);
|
||||||
bGroup = nToLast(bGroups, i);
|
bGroup = bGroups.at(-i);
|
||||||
}
|
}
|
||||||
|
|
||||||
aGroup = aGroup ?? a;
|
aGroup = aGroup ?? a;
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
import { describe, expect, test } from 'vitest';
|
|
||||||
|
|
||||||
import { isEqual } from '../utils/index.js';
|
|
||||||
|
|
||||||
describe('isEqual', () => {
|
|
||||||
test('number', () => {
|
|
||||||
expect(isEqual(1, 1)).toBe(true);
|
|
||||||
expect(isEqual(1, 114514)).toBe(false);
|
|
||||||
expect(isEqual(NaN, NaN)).toBe(true);
|
|
||||||
expect(isEqual(0, -0)).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('string', () => {
|
|
||||||
expect(isEqual('', '')).toBe(true);
|
|
||||||
expect(isEqual('', ' ')).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('array', () => {
|
|
||||||
expect(isEqual([], [])).toBe(true);
|
|
||||||
expect(isEqual([1, 1, 4, 5, 1, 4], [])).toBe(false);
|
|
||||||
expect(isEqual([1, 1, 4, 5, 1, 4], [1, 1, 4, 5, 1, 4])).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('object', () => {
|
|
||||||
expect(isEqual({}, {})).toBe(true);
|
|
||||||
expect(
|
|
||||||
isEqual(
|
|
||||||
{
|
|
||||||
f: 1,
|
|
||||||
g: {
|
|
||||||
o: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
f: 1,
|
|
||||||
g: {
|
|
||||||
o: '',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
).toBe(true);
|
|
||||||
expect(isEqual({}, { foo: 1 })).toBe(false);
|
|
||||||
// @ts-expect-error ignore
|
|
||||||
expect(isEqual({ foo: 1 }, {})).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('nested', () => {
|
|
||||||
const nested = {
|
|
||||||
string: 'this is a string',
|
|
||||||
integer: 42,
|
|
||||||
array: [19, 19, 810, 'test', NaN],
|
|
||||||
nestedArray: [
|
|
||||||
[1, 2],
|
|
||||||
[3, 4],
|
|
||||||
],
|
|
||||||
float: 114.514,
|
|
||||||
undefined,
|
|
||||||
object: {
|
|
||||||
'first-child': true,
|
|
||||||
'second-child': false,
|
|
||||||
'last-child': null,
|
|
||||||
},
|
|
||||||
bigint: 110101195306153019n,
|
|
||||||
};
|
|
||||||
expect(isEqual(nested, nested)).toBe(true);
|
|
||||||
// @ts-expect-error ignore
|
|
||||||
expect(isEqual({ foo: [] }, { foo: '' })).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
export * from './crypto.js';
|
export * from './crypto.js';
|
||||||
export * from './disposable.js';
|
export * from './disposable.js';
|
||||||
export * from './function.js';
|
export * from './function.js';
|
||||||
export * from './is-equal.js';
|
|
||||||
export * from './iterable.js';
|
|
||||||
export * from './logger.js';
|
export * from './logger.js';
|
||||||
export * from './signal-watcher.js';
|
export * from './signal-watcher.js';
|
||||||
export * from './slot.js';
|
export * from './slot.js';
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
// https://stackoverflow.com/questions/31538010/test-if-a-variable-is-a-primitive-rather-than-an-object
|
|
||||||
export function isPrimitive(
|
|
||||||
a: unknown
|
|
||||||
): a is null | undefined | boolean | number | string {
|
|
||||||
return a !== Object(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function assertType<T>(_: unknown): asserts _ is T {}
|
|
||||||
|
|
||||||
export type Equals<X, Y> =
|
|
||||||
///
|
|
||||||
(<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
|
|
||||||
type Allowed =
|
|
||||||
| unknown
|
|
||||||
| void
|
|
||||||
| null
|
|
||||||
| undefined
|
|
||||||
| boolean
|
|
||||||
| number
|
|
||||||
| string
|
|
||||||
| unknown[]
|
|
||||||
| object;
|
|
||||||
export function isEqual<T extends Allowed, U extends T>(
|
|
||||||
val: T,
|
|
||||||
expected: U
|
|
||||||
): Equals<T, U> {
|
|
||||||
const a = isPrimitive(val);
|
|
||||||
const b = isPrimitive(expected);
|
|
||||||
if (a && b) {
|
|
||||||
if (!Object.is(val, expected)) {
|
|
||||||
return false as Equals<T, U>;
|
|
||||||
}
|
|
||||||
} else if (a !== b) {
|
|
||||||
return false as Equals<T, U>;
|
|
||||||
} else {
|
|
||||||
if (Array.isArray(val) && Array.isArray(expected)) {
|
|
||||||
if (val.length !== expected.length) {
|
|
||||||
return false as Equals<T, U>;
|
|
||||||
}
|
|
||||||
return val.every((x, i) => isEqual(x, expected[i])) as Equals<T, U>;
|
|
||||||
} else if (typeof val === 'object' && typeof expected === 'object') {
|
|
||||||
const obj1 = Object.entries(val as Record<string, unknown>);
|
|
||||||
const obj2 = Object.entries(expected as Record<string, unknown>);
|
|
||||||
if (obj1.length !== obj2.length) {
|
|
||||||
return false as Equals<T, U>;
|
|
||||||
}
|
|
||||||
return obj1.every((x, i) => isEqual(x, obj2[i])) as Equals<T, U>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true as Equals<T, U>;
|
|
||||||
}
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* const items = [
|
|
||||||
* {name: 'a', classroom: 'c1'},
|
|
||||||
* {name: 'b', classroom: 'c2'},
|
|
||||||
* {name: 'a', classroom: 't0'}
|
|
||||||
* ]
|
|
||||||
* const counted = countBy(items1, i => i.name);
|
|
||||||
* // counted: { a: 2, b: 1}
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export function countBy<T>(
|
|
||||||
items: T[],
|
|
||||||
key: (item: T) => string | number | null
|
|
||||||
): Record<string, number> {
|
|
||||||
const count: Record<string, number> = {};
|
|
||||||
items.forEach(item => {
|
|
||||||
const k = key(item);
|
|
||||||
if (k === null) return;
|
|
||||||
if (!count[k]) {
|
|
||||||
count[k] = 0;
|
|
||||||
}
|
|
||||||
count[k] += 1;
|
|
||||||
});
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* const items = [{n: 1}, {n: 2}]
|
|
||||||
* const max = maxBy(items, i => i.n);
|
|
||||||
* // max: {n: 2}
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export function maxBy<T>(items: T[], value: (item: T) => number): T | null {
|
|
||||||
if (!items.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
let maxItem = items[0];
|
|
||||||
let max = value(maxItem);
|
|
||||||
|
|
||||||
for (let i = 1; i < items.length; i++) {
|
|
||||||
const item = items[i];
|
|
||||||
const v = value(item);
|
|
||||||
if (v > max) {
|
|
||||||
max = v;
|
|
||||||
maxItem = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if there are at least `n` elements in the array that match the given condition.
|
|
||||||
*
|
|
||||||
* @param arr - The input array of elements.
|
|
||||||
* @param matchFn - A function that takes an element of the array and returns a boolean value
|
|
||||||
* indicating if the element matches the desired condition.
|
|
||||||
* @param n - The minimum number of matching elements required.
|
|
||||||
* @returns A boolean value indicating if there are at least `n` matching elements in the array.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const arr = [1, 2, 3, 4, 5];
|
|
||||||
* const isEven = (num: number): boolean => num % 2 === 0;
|
|
||||||
* console.log(atLeastNMatches(arr, isEven, 2)); // Output: true
|
|
||||||
*/
|
|
||||||
export function atLeastNMatches<T>(
|
|
||||||
arr: T[],
|
|
||||||
matchFn: (element: T) => boolean,
|
|
||||||
n: number
|
|
||||||
): boolean {
|
|
||||||
let count = 0;
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
|
||||||
if (matchFn(arr[i])) {
|
|
||||||
count++;
|
|
||||||
|
|
||||||
if (count >= n) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Groups an array of elements based on a provided key function.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* interface Student {
|
|
||||||
* name: string;
|
|
||||||
* age: number;
|
|
||||||
* }
|
|
||||||
* const students: Student[] = [
|
|
||||||
* { name: 'Alice', age: 25 },
|
|
||||||
* { name: 'Bob', age: 23 },
|
|
||||||
* { name: 'Cathy', age: 25 },
|
|
||||||
* ];
|
|
||||||
* const groupedByAge = groupBy(students, (student) => student.age.toString());
|
|
||||||
* console.log(groupedByAge);
|
|
||||||
* // Output: {
|
|
||||||
* '23': [ { name: 'Bob', age: 23 } ],
|
|
||||||
* '25': [ { name: 'Alice', age: 25 }, { name: 'Cathy', age: 25 } ]
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
export function groupBy<T, K extends string>(
|
|
||||||
arr: T[],
|
|
||||||
key: K | ((item: T) => K)
|
|
||||||
): Record<K, T[]> {
|
|
||||||
const result = {} as Record<string, T[]>;
|
|
||||||
|
|
||||||
for (const item of arr) {
|
|
||||||
const groupKey = (
|
|
||||||
typeof key === 'function' ? key(item) : (item as any)[key]
|
|
||||||
) as string;
|
|
||||||
|
|
||||||
if (!result[groupKey]) {
|
|
||||||
result[groupKey] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
result[groupKey].push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function pickArray<T>(target: Array<T>, keys: number[]): Array<T> {
|
|
||||||
return keys.reduce((pre, key) => {
|
|
||||||
pre.push(target[key]);
|
|
||||||
return pre;
|
|
||||||
}, [] as T[]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function pick<T, K extends keyof T>(
|
|
||||||
target: T,
|
|
||||||
keys: K[]
|
|
||||||
): Record<K, T[K]> {
|
|
||||||
return keys.reduce(
|
|
||||||
(pre, key) => {
|
|
||||||
pre[key] = target[key];
|
|
||||||
return pre;
|
|
||||||
},
|
|
||||||
{} as Record<K, T[K]>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function pickValues<T, K extends keyof T>(
|
|
||||||
target: T,
|
|
||||||
keys: K[]
|
|
||||||
): Array<T[K]> {
|
|
||||||
return keys.reduce(
|
|
||||||
(pre, key) => {
|
|
||||||
pre.push(target[key]);
|
|
||||||
return pre;
|
|
||||||
},
|
|
||||||
[] as Array<T[K]>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function lastN<T>(target: Array<T>, n: number) {
|
|
||||||
return target.slice(target.length - n, target.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isEmpty(obj: unknown) {
|
|
||||||
if (Object.getPrototypeOf(obj) === Object.prototype) {
|
|
||||||
return Object.keys(obj as object).length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(obj) || typeof obj === 'string') {
|
|
||||||
return (obj as Array<unknown>).length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function keys<T>(obj: T): (keyof T)[] {
|
|
||||||
return Object.keys(obj as object) as (keyof T)[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function values<T>(obj: T): T[keyof T][] {
|
|
||||||
return Object.values(obj as object);
|
|
||||||
}
|
|
||||||
|
|
||||||
type IterableType<T> = T extends Array<infer U> ? U : T;
|
|
||||||
|
|
||||||
export function last<T extends Iterable<unknown>>(
|
|
||||||
iterable: T
|
|
||||||
): IterableType<T> | undefined {
|
|
||||||
if (Array.isArray(iterable)) {
|
|
||||||
return iterable[iterable.length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
let last: unknown | undefined;
|
|
||||||
for (const item of iterable) {
|
|
||||||
last = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
return last as IterableType<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nToLast<T extends Iterable<unknown>>(
|
|
||||||
iterable: T,
|
|
||||||
n: number
|
|
||||||
): IterableType<T> | undefined {
|
|
||||||
if (Array.isArray(iterable)) {
|
|
||||||
return iterable[iterable.length - n];
|
|
||||||
}
|
|
||||||
|
|
||||||
const arr = [...iterable];
|
|
||||||
|
|
||||||
return arr[arr.length - n] as IterableType<T>;
|
|
||||||
}
|
|
||||||
@@ -10,3 +10,5 @@ export type DeepPartial<T> = {
|
|||||||
: DeepPartial<T[P]>
|
: DeepPartial<T[P]>
|
||||||
: T[P];
|
: T[P];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function assertType<T>(_: unknown): asserts _ is T {}
|
||||||
|
|||||||
@@ -13,8 +13,10 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blocksuite/global": "workspace:*",
|
"@blocksuite/global": "workspace:*",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
"idb": "^8.0.0",
|
"idb": "^8.0.0",
|
||||||
"idb-keyval": "^6.2.1",
|
"idb-keyval": "^6.2.1",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
"y-protocols": "^1.0.6"
|
"y-protocols": "^1.0.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { isEqual, type Logger, Slot } from '@blocksuite/global/utils';
|
import { type Logger, Slot } from '@blocksuite/global/utils';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
import type { Doc } from 'yjs';
|
import type { Doc } from 'yjs';
|
||||||
import {
|
import {
|
||||||
applyUpdate,
|
applyUpdate,
|
||||||
|
|||||||
@@ -2638,10 +2638,10 @@ __metadata:
|
|||||||
"@lit/context": "npm:^1.1.2"
|
"@lit/context": "npm:^1.1.2"
|
||||||
"@preact/signals-core": "npm:^1.8.0"
|
"@preact/signals-core": "npm:^1.8.0"
|
||||||
"@toeverything/theme": "npm:^1.1.12"
|
"@toeverything/theme": "npm:^1.1.12"
|
||||||
"@types/lodash.chunk": "npm:^4.2.9"
|
"@types/lodash-es": "npm:^4.17.12"
|
||||||
fractional-indexing: "npm:^3.2.0"
|
fractional-indexing: "npm:^3.2.0"
|
||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
lodash.chunk: "npm:^4.2.0"
|
lodash-es: "npm:^4.17.21"
|
||||||
nanoid: "npm:^5.0.7"
|
nanoid: "npm:^5.0.7"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
@@ -2661,11 +2661,11 @@ __metadata:
|
|||||||
"@lit/context": "npm:^1.1.2"
|
"@lit/context": "npm:^1.1.2"
|
||||||
"@preact/signals-core": "npm:^1.8.0"
|
"@preact/signals-core": "npm:^1.8.0"
|
||||||
"@toeverything/theme": "npm:^1.1.12"
|
"@toeverything/theme": "npm:^1.1.12"
|
||||||
"@types/lodash.chunk": "npm:^4.2.9"
|
"@types/lodash-es": "npm:^4.17.12"
|
||||||
fractional-indexing: "npm:^3.2.0"
|
fractional-indexing: "npm:^3.2.0"
|
||||||
html2canvas: "npm:^1.4.1"
|
html2canvas: "npm:^1.4.1"
|
||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
lodash.chunk: "npm:^4.2.0"
|
lodash-es: "npm:^4.17.21"
|
||||||
nanoid: "npm:^5.0.7"
|
nanoid: "npm:^5.0.7"
|
||||||
pdf-lib: "npm:^1.17.1"
|
pdf-lib: "npm:^1.17.1"
|
||||||
vitest: "npm:3.0.7"
|
vitest: "npm:3.0.7"
|
||||||
@@ -2786,7 +2786,9 @@ __metadata:
|
|||||||
"@blocksuite/inline": "workspace:*"
|
"@blocksuite/inline": "workspace:*"
|
||||||
"@blocksuite/store": "workspace:*"
|
"@blocksuite/store": "workspace:*"
|
||||||
"@toeverything/theme": "npm:^1.1.12"
|
"@toeverything/theme": "npm:^1.1.12"
|
||||||
|
"@types/lodash-es": "npm:^4.17.12"
|
||||||
fractional-indexing: "npm:^3.2.0"
|
fractional-indexing: "npm:^3.2.0"
|
||||||
|
lodash-es: "npm:^4.17.21"
|
||||||
yjs: "npm:^13.6.21"
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
@@ -3062,8 +3064,10 @@ __metadata:
|
|||||||
"@lit/context": "npm:^1.1.2"
|
"@lit/context": "npm:^1.1.2"
|
||||||
"@preact/signals-core": "npm:^1.8.0"
|
"@preact/signals-core": "npm:^1.8.0"
|
||||||
"@toeverything/theme": "npm:^1.1.12"
|
"@toeverything/theme": "npm:^1.1.12"
|
||||||
|
"@types/lodash-es": "npm:^4.17.12"
|
||||||
date-fns: "npm:^4.0.0"
|
date-fns: "npm:^4.0.0"
|
||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
|
lodash-es: "npm:^4.17.21"
|
||||||
yjs: "npm:^13.6.21"
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
@@ -3233,8 +3237,10 @@ __metadata:
|
|||||||
resolution: "@blocksuite/sync@workspace:blocksuite/framework/sync"
|
resolution: "@blocksuite/sync@workspace:blocksuite/framework/sync"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@blocksuite/global": "workspace:*"
|
"@blocksuite/global": "workspace:*"
|
||||||
|
"@types/lodash-es": "npm:^4.17.12"
|
||||||
idb: "npm:^8.0.0"
|
idb: "npm:^8.0.0"
|
||||||
idb-keyval: "npm:^6.2.1"
|
idb-keyval: "npm:^6.2.1"
|
||||||
|
lodash-es: "npm:^4.17.21"
|
||||||
vitest: "npm:3.0.7"
|
vitest: "npm:3.0.7"
|
||||||
y-protocols: "npm:^1.0.6"
|
y-protocols: "npm:^1.0.6"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -14145,15 +14151,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/lodash.chunk@npm:^4.2.9":
|
|
||||||
version: 4.2.9
|
|
||||||
resolution: "@types/lodash.chunk@npm:4.2.9"
|
|
||||||
dependencies:
|
|
||||||
"@types/lodash": "npm:*"
|
|
||||||
checksum: 10/ccffe7273a0941655d5b988baeffa8f7d4d19a8b43ed728ff4e616013506efe85914ba99d4ec299e0106506e1bca3923b065eabb0aa5f1e4b18f68e790ae6b88
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@types/lodash.clonedeep@npm:^4.5.9":
|
"@types/lodash.clonedeep@npm:^4.5.9":
|
||||||
version: 4.5.9
|
version: 4.5.9
|
||||||
resolution: "@types/lodash.clonedeep@npm:4.5.9"
|
resolution: "@types/lodash.clonedeep@npm:4.5.9"
|
||||||
@@ -24222,13 +24219,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"lodash.chunk@npm:^4.2.0":
|
|
||||||
version: 4.2.0
|
|
||||||
resolution: "lodash.chunk@npm:4.2.0"
|
|
||||||
checksum: 10/3b6639fda107a0d8c3996090eeb7ad0f05063e6a1f4692a01335e7c1990030d3274c3164d78159f24928d86eb0943ad326b0a4a2da706c250c4d3166ddd8ed0e
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"lodash.clonedeep@npm:^4.5.0":
|
"lodash.clonedeep@npm:^4.5.0":
|
||||||
version: 4.5.0
|
version: 4.5.0
|
||||||
resolution: "lodash.clonedeep@npm:4.5.0"
|
resolution: "lodash.clonedeep@npm:4.5.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user