@fulate/tools 1.0.12 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # @fulate/tools Editor integration
1
+ # @fulate/tools Editor integration
2
+
3
+ > 文档角色:`GUIDE`。说明当前 Tools 用法;Editor 时序的唯一合同见 [Editor 规范](../../docs/specs/editor-interaction.md)。
2
4
 
3
5
  每个活动 Root 只有一个 `EditorInteractionController`。它拥有 selection、输入仲裁、Transform/Point
4
6
  gesture、Content session、Line/LineTree branch draft 与 semantic History 边界;`Select` 只保留 command/paint
@@ -130,7 +132,51 @@ History 安装后排队一次 `select:configured-change` 通知;标量 noop
130
132
  width/height/x/y 仍使用 `Select.resize()` 或其他 Transform 命令,不能用普通 authored patch 绕过
131
133
  父级矩阵反算。
132
134
 
133
- `Select.resize()` 是属性面板使用的公开尺寸命令:
135
+ ### 应用组合命令
136
+
137
+ 不同 owner 的属性和结构组合使用 `select.applyCommand(createCommand)`。构造函数在旧交互结束、
138
+ pending 几何稳定后同步运行,参数是当时的 live selection,返回公开的 `SelectCommand`:
139
+
140
+ ```ts
141
+ const changed = select.applyCommand(() => ({
142
+ ownerChanges: [{ owner: workspace, patch: { backgroundColor: "#ffffff" } }],
143
+ recordHistory: false
144
+ }));
145
+
146
+ select.applyCommand(() => ({
147
+ structureChanges: [{ owner: layer, children: [...layer.children, newShape] }],
148
+ selectionAfter: [newShape],
149
+ afterInstall: () => attachApplicationData(newShape)
150
+ }));
151
+ ```
152
+
153
+ `recordHistory: false` 只关闭本命令的记录;默认仍服从 `select.history.enabled`。返回值只表示本命令
154
+ Canvas configured 属性或结构的实际净变化,与 History、监听器是否开启无关。已有拖拽完成和随后命令
155
+ 是两个操作,各自有适用的 History/配置通知;本命令 noop 不撤销前一个操作。
156
+
157
+ `selectionAfter` 省略时保留当前选择意图;结构提交后过滤已移除节点和被选中祖先覆盖的元素,成员未变
158
+ 时保留当前 Point 等选择状态。`[]` 清空。显式选择结果或实际选择修复排队一次 `select:end`;
159
+ 仅选择变化返回 false,不生成 History/配置通知。构造返回 undefined、空命令、相同值
160
+ 和同 owner 最终覆盖回原值都是普通 noop,`afterInstall` 不运行。
161
+
162
+ `afterInstall` 位于 Core 字段/结构、lifecycle、hook、scene observers 及选择安装之后,frame drain、
163
+ History finish 和排队配置完成通知之前。它只在实际 Scene 安装后同步调用一次,不随 undo/redo 重放;
164
+ 应用自己的数据对应关系仍由自己的注册/清理链维护。回调异常直接传播,已安装的正常变化保留。
165
+ 构造阶段销毁 Select/Root 时停止本命令;安装后销毁则保留已安装变化并停止旧 controller 的后续完成。
166
+
167
+ 命令 caller 不需要 prepare 属性、操作 History scope 或驱动帧。只需单独结束当前交互时使用
168
+ `select.finishCurrentInteraction()`:完成已接受交互,取消尚未提交的画线草稿,无活动交互时无操作。
169
+
170
+ 需要当前 Workspace 作为对齐参考范围时,延迟到内置 align 的稳定阶段读取:
171
+
172
+ ```ts
173
+ select.align(AlignType.JustifyEnd, () => workspace.transform.getRenderCoverageBounds());
174
+ ```
175
+
176
+ 参考函数最多同步调用一次,几何稳定后读取;静态 world Rect 仍直接传入。矩阵/children 的构造同样应
177
+ 放入 `applyCommand` 的同步构造函数。完整参数与时序见 [Editor 规范](../../docs/specs/editor-interaction.md#64-应用公开命令边界)。
178
+
179
+ `Select.resize()` 是属性面板使用的公开尺寸命令:
134
180
 
135
181
  ```ts
136
182
  const bounds = element.transform.getWorldVisualBoundsView();
@@ -3,7 +3,7 @@ import { LineTree, type LineTreeBranchTailSource, type LineDecoration } from "@f
3
3
  import { type PointView, type Rect } from "@fulate/share";
4
4
  import type { HistoryManager, HistoryScope } from "../../history";
5
5
  import type { LineTool } from "../../line";
6
- import type { Select, SelectedPropertyPatch } from "../../select";
6
+ import type { Select, SelectCommand, SelectedPropertyPatch } from "../../select";
7
7
  import { type SelectionOverlayProjection, type SelectionOverlayTarget } from "../../select/projection";
8
8
  import { type FlipDirection, type ResizeOptions } from "../../select/transform";
9
9
  import type { Snap } from "../../select/snap";
@@ -159,7 +159,9 @@ export declare class EditorInteractionController {
159
159
  snap: import("../../select/snap").PortSnapResult | null;
160
160
  };
161
161
  hasLineToolSession(tool: LineTool): boolean;
162
- applyCommand(ownerEffects: readonly OwnerPropertyChange[], structureEffects: readonly StructureChange[], scope: HistoryScope | undefined, selectionAfter: readonly Element[], options?: ApplyCommandOptions): void;
162
+ /** 同一命令 owner 的公开入口,构造只在当前交互和几何稳定后运行。 */
163
+ executeCommand(createCommand: (selection: readonly Element[]) => SelectCommand | undefined): boolean;
164
+ applyCommand(ownerEffects: readonly OwnerPropertyChange[], structureEffects: readonly StructureChange[], scope: HistoryScope | undefined, selectionAfter: readonly Element[] | undefined, options?: ApplyCommandOptions): boolean;
163
165
  finishCurrentInteraction(): void;
164
166
  destroy(): void;
165
167
  }
@@ -25,7 +25,7 @@ export interface PointerGesture {
25
25
  finish(intent?: PointerIntent, cancelled?: boolean): void;
26
26
  }
27
27
  export interface ApplyCommandOptions {
28
- readonly beforeDrain?: () => void;
28
+ readonly afterInstall?: () => void;
29
29
  readonly afterHistory?: () => void;
30
30
  readonly installSelection?: () => boolean;
31
31
  }
@@ -65,7 +65,10 @@ export declare class HistoryManager {
65
65
  get undoCount(): number;
66
66
  get redoCount(): number;
67
67
  bindSelection(adapter: HistorySelectionAdapter | null): void;
68
- openScope(selectionBefore?: readonly Element<import("@fulate/core").ElementProperties, import("@fulate/core").BaseElementOption<any>, Partial<Omit<import("@fulate/core").BaseElementOption<any>, "key" | "children">>>[]): HistoryScope | undefined;
68
+ openScope(selectionBefore?: readonly Element<import("@fulate/core").ElementProperties, import("@fulate/core").BaseElementOption<any>, Partial<Omit<import("@fulate/core").BaseElementOption<any>, "key" | "children">>>[], options?: {
69
+ readonly recordHistory?: boolean;
70
+ readonly trackChanges?: boolean;
71
+ }): HistoryScope | undefined;
69
72
  /** @internal Publishes one completed actual configured semantic change. */
70
73
  publishConfiguredChange(changed: boolean | undefined): void;
71
74
  /** @internal 只由存在Canvas净变化或外部change的scope完成时写入。 */
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Select } from "./select/index";
2
- export type { ConnectionGesture, CopyContext, ClipboardDataProducer, DeleteContext, FlipDirection, PasteContext, PasteOptions, PasteParentResolver, ResizeAnchor, ResizeOptions, SelectedPropertyPatch, SelectKeyboardCommands, SelectOption, ToolsConnectionIntent } from "./select/index";
2
+ export type { ConnectionGesture, CopyContext, ClipboardDataProducer, DeleteContext, FlipDirection, PasteContext, PasteOptions, PasteParentResolver, ResizeAnchor, ResizeOptions, SelectedPropertyPatch, SelectCommand, SelectKeyboardCommands, SelectOption, ToolsConnectionIntent } from "./select/index";
3
3
  export { Snap } from "./select/snap";
4
4
  export { HistoryManager } from "./history/index";
5
5
  export type { EditorHistoryEntry, HistoryChange, HistoryPlacementChange, HistoryPropertyChange, HistoryScope } from "./history/index";
@@ -10,5 +10,6 @@ export type { RuleOption } from "./rule/index";
10
10
  export { EditorLayer } from "./editor-layer";
11
11
  export { alignElements } from "./select/align";
12
12
  export { AlignType } from "./select/align";
13
+ export type { AlignReference } from "./select/align";
13
14
  export { ArrangeType } from "./select/arrange";
14
15
  export type { ClipboardPlugin } from "./select/clipboard";
package/dist/index.js CHANGED
@@ -1282,18 +1282,19 @@ var EditorInteractionController = class {
1282
1282
  restoreSelectionForHistory(elements) {
1283
1283
  this.replaceSelection(elements);
1284
1284
  }
1285
- replaceSelection(elements) {
1285
+ replaceSelection(elements, onlyIfChanged = false) {
1286
1286
  this.pendingSelectionRepair = null;
1287
- if (this.selectState?.kind !== "content") this.installSelectState({
1288
- kind: "idle",
1289
- gesture: null
1290
- });
1291
1287
  const selected = /* @__PURE__ */ new Set();
1292
1288
  for (const element of elements) if (element.activeRoot === this.root) selected.add(element);
1293
1289
  const topLevel = [...selected].filter((element) => {
1294
1290
  for (let parent = element.parent; parent; parent = parent.parent) if (selected.has(parent)) return false;
1295
1291
  return true;
1296
1292
  });
1293
+ if (onlyIfChanged && topLevel.length === this.selection.length && topLevel.every((element, index) => element === this.selection[index])) return;
1294
+ if (this.selectState?.kind !== "content") this.installSelectState({
1295
+ kind: "idle",
1296
+ gesture: null
1297
+ });
1297
1298
  const owners = [];
1298
1299
  for (const element of topLevel) {
1299
1300
  const behavior = getEditorCapability(element, SelectionBehaviorCapabilityToken);
@@ -1519,7 +1520,7 @@ var EditorInteractionController = class {
1519
1520
  this.select.transform.markPaintDirty();
1520
1521
  }
1521
1522
  applyAuthoredBatch(ownerEffects, structureEffects, scope) {
1522
- this.root.applyChangeBatch(ownerEffects, structureEffects, scope);
1523
+ return this.root.applyChangeBatch(ownerEffects, structureEffects, scope);
1523
1524
  }
1524
1525
  onPointerDown(event) {
1525
1526
  if (this.activeGesture) return;
@@ -2550,26 +2551,53 @@ var EditorInteractionController = class {
2550
2551
  hasLineToolSession(tool) {
2551
2552
  return this.lineSession?.tool === tool || this.lineTreeSession?.tool === tool;
2552
2553
  }
2554
+ /** 同一命令 owner 的公开入口,构造只在当前交互和几何稳定后运行。 */
2555
+ executeCommand(createCommand) {
2556
+ this.finishCurrentInteraction();
2557
+ if (this.select.interactionController !== this) return false;
2558
+ this.root.frameRuntime.drain();
2559
+ if (this.select.interactionController !== this) return false;
2560
+ const command = createCommand(this.selection);
2561
+ if (this.select.interactionController !== this || !command) return false;
2562
+ const scope = this.history.openScope(this.selection, {
2563
+ recordHistory: command.recordHistory,
2564
+ trackChanges: true
2565
+ });
2566
+ return this.applyCommand(resolveConnectionPortChanges(this.root, command.ownerChanges ?? []), command.structureChanges ?? [], scope, command.selectionAfter, command);
2567
+ }
2553
2568
  applyCommand(ownerEffects, structureEffects, scope, selectionAfter, options) {
2554
2569
  const selectionOwners = this.owners;
2570
+ const selectionBefore = this.selection;
2555
2571
  let installedSelection;
2556
- this.applyAuthoredBatch(ownerEffects, structureEffects, scope);
2557
- if (options?.installSelection ? options.installSelection() : this.owners === selectionOwners || this.pendingSelectionRepair === this.owners) {
2558
- this.replaceSelection(selectionAfter);
2572
+ const installed = this.applyAuthoredBatch(ownerEffects, structureEffects, scope);
2573
+ if (this.select.interactionController !== this) {
2574
+ scope?.discard();
2575
+ return installed;
2576
+ }
2577
+ const canInstallSelection = (selectionAfter !== void 0 || installed && structureEffects.length > 0) && (options?.installSelection ? options.installSelection() : this.owners === selectionOwners || this.pendingSelectionRepair === this.owners);
2578
+ if (canInstallSelection) {
2579
+ this.replaceSelection(selectionAfter ?? this.selection, selectionAfter === void 0);
2559
2580
  if (options?.installSelection) installedSelection = {
2560
2581
  owners: this.owners,
2561
2582
  interaction: this.controllerState
2562
2583
  };
2563
2584
  }
2564
- options?.beforeDrain?.();
2585
+ const selectionRepaired = canInstallSelection && this.selection.length !== selectionBefore.length;
2586
+ if (installed) options?.afterInstall?.();
2565
2587
  if (this.select.interactionController !== this) {
2566
2588
  scope?.discard();
2567
- return;
2589
+ return installed;
2568
2590
  }
2569
2591
  this.root.frameRuntime.drain();
2570
- this.publishConfiguredChange(scope?.finish(this.selection));
2592
+ if (this.select.interactionController !== this) {
2593
+ scope?.discard();
2594
+ return installed;
2595
+ }
2596
+ const changed = scope?.finish(this.selection) ?? installed;
2597
+ this.publishConfiguredChange(changed);
2571
2598
  options?.afterHistory?.();
2572
- if (!options?.installSelection || installedSelection?.owners === this.owners && installedSelection.interaction === this.controllerState) this.notifySelect("select:end");
2599
+ if ((selectionAfter !== void 0 || selectionRepaired) && (!options?.installSelection || installedSelection?.owners === this.owners && installedSelection.interaction === this.controllerState)) this.notifySelect("select:end");
2600
+ return changed;
2573
2601
  }
2574
2602
  finishCurrentInteraction() {
2575
2603
  if (this.contentSession) {
@@ -2741,9 +2769,9 @@ var HistoryManager = class {
2741
2769
  bindSelection(adapter) {
2742
2770
  this.selectionAdapter = adapter;
2743
2771
  }
2744
- openScope(selectionBefore = this.selectionAdapter?.getSelection() ?? []) {
2745
- const recordHistory = this.enabled;
2746
- if (!recordHistory && !this.selectionAdapter?.hasConfiguredChangeListener()) return void 0;
2772
+ openScope(selectionBefore = this.selectionAdapter?.getSelection() ?? [], options) {
2773
+ const recordHistory = this.enabled && options?.recordHistory !== false;
2774
+ if (!recordHistory && !options?.trackChanges && !this.selectionAdapter?.hasConfiguredChangeListener()) return void 0;
2747
2775
  return new ActiveHistoryScope(this, recordHistory ? selectionKeys(selectionBefore) : null, recordHistory);
2748
2776
  }
2749
2777
  /** @internal Publishes one completed actual configured semantic change. */
@@ -3002,10 +3030,13 @@ function alignElements(select, type, referenceRect) {
3002
3030
  const minimum = referenceRect ? between ? 2 : 1 : between ? 3 : 2;
3003
3031
  if (elements.length < minimum) return;
3004
3032
  controller.finishCurrentInteraction();
3033
+ if (select.interactionController !== controller) return;
3005
3034
  controller.root.frameRuntime.drain();
3006
3035
  if (select.interactionController !== controller) return;
3007
3036
  elements = controller.selection;
3008
3037
  if (elements.length < minimum) return;
3038
+ const reference = typeof referenceRect === "function" ? referenceRect() : referenceRect;
3039
+ if (select.interactionController !== controller) return;
3009
3040
  const rects = elements.map((element) => {
3010
3041
  const transform = getEditorCapability(element, TransformInteractionCapabilityToken);
3011
3042
  const bounds = getWorldSelectionBounds(element, transform);
@@ -3020,7 +3051,7 @@ function alignElements(select, type, referenceRect) {
3020
3051
  dy: 0
3021
3052
  };
3022
3053
  });
3023
- resolveOffsets(rects, type, referenceRect ?? makeBoundingBoxFromRects(rects));
3054
+ resolveOffsets(rects, type, reference ?? makeBoundingBoxFromRects(rects));
3024
3055
  const changes = [];
3025
3056
  for (const rect of rects) {
3026
3057
  if (rect.dx === 0 && rect.dy === 0) continue;
@@ -3409,7 +3440,7 @@ function pasteData(select, controller, pasteSelection, task, data, deserializers
3409
3440
  const scope = controller.history.openScope(controller.selection);
3410
3441
  const installSelection = () => controller.ownsPasteSelection(pasteSelection, task);
3411
3442
  controller.applyCommand(changes, appendStructure(placements), scope, elements, options?.afterInstall ? {
3412
- beforeDrain: () => options.afterInstall({
3443
+ afterInstall: () => options.afterInstall({
3413
3444
  applicationData: data.applicationData,
3414
3445
  keyMap,
3415
3446
  history: recordHistory ? scope : void 0
@@ -3484,7 +3515,7 @@ function deleteElements(select, afterInstall) {
3484
3515
  const recordsHistory = select.history.enabled;
3485
3516
  const scope = select.history.openScope(selected);
3486
3517
  controller.applyCommand([], structure, scope, [], {
3487
- beforeDrain: afterInstall ? () => afterInstall({
3518
+ afterInstall: afterInstall ? () => afterInstall({
3488
3519
  elements: subjects,
3489
3520
  history: recordsHistory ? scope : void 0
3490
3521
  }) : void 0,
@@ -3899,6 +3930,19 @@ var Select = class extends Element {
3899
3930
  select(elements) {
3900
3931
  this.controller?.setSelection(elements);
3901
3932
  }
3933
+ /** 完成已接受的当前交互,取消未提交的画线草稿;无活动交互时无操作。 */
3934
+ finishCurrentInteraction() {
3935
+ this.controller?.finishCurrentInteraction();
3936
+ }
3937
+ /**
3938
+ * 先结束旧交互并稳定几何,再同步调用 createCommand,传入 live selection。
3939
+ * 返回本命令 Canvas configured 的净变化,与 History/监听器是否开启无关;不包含旧交互。
3940
+ * 返回 undefined 的构造或空/相同值命令是普通 noop。未激活的 Select 不调用构造。
3941
+ * 普通选区同一 patch 使用 setProperties;此入口用于 owner-specific 与结构组合操作。
3942
+ */
3943
+ applyCommand(createCommand) {
3944
+ return this.controller?.executeCommand(createCommand) ?? false;
3945
+ }
3902
3946
  /**
3903
3947
  * Groups the live multi-selection. Accepted active Transform work finishes
3904
3948
  * before the independent Group command; stale pointer continuation is ignored.
@@ -3918,7 +3962,8 @@ var Select = class extends Element {
3918
3962
  /**
3919
3963
  * Aligns the live selection in world space. Without `referenceRect`, the
3920
3964
  * current selection-frame AABB is the reference. A supplied world Rect is
3921
- * used directly. Distribution keeps strict edge gaps when they are numerically
3965
+ * used directly; a reference callback runs once after the previous interaction
3966
+ * and pending geometry finish. Distribution keeps strict edge gaps when they are numerically
3922
3967
  * possible and uses bounded overlap when the selected sizes exceed the reference,
3923
3968
  * while keeping every selection-frame AABB inside it and preserving order. The
3924
3969
  * current axis is a noop only when an element cannot fit or no ordered layout is
@@ -11,4 +11,6 @@ export declare enum AlignType {
11
11
  AlignEnd = "align-end",
12
12
  AlignBetween = "align-between"
13
13
  }
14
- export declare function alignElements(select: Select, type: AlignType, referenceRect?: Readonly<Rect>): void;
14
+ /** World reference Rect, or a synchronous read after interaction and geometry completion. */
15
+ export type AlignReference = Readonly<Rect> | (() => Readonly<Rect>);
16
+ export declare function alignElements(select: Select, type: AlignType, referenceRect?: AlignReference): void;
@@ -1,8 +1,7 @@
1
- import { Element, ElementProperties, type BaseElementOption, type ConnectionPortRef, type Layer, type Root } from "@fulate/core";
2
- import type { Rect } from "@fulate/share";
1
+ import { Element, ElementProperties, type BaseElementOption, type ConnectionPortRef, type Layer, type Root, type OwnerPropertyChange, type StructureChange } from "@fulate/core";
3
2
  import { EditorInteractionController } from "../editor/interaction-controller";
4
3
  import { HistoryManager } from "../history";
5
- import { type AlignType } from "./align";
4
+ import { type AlignType, type AlignReference } from "./align";
6
5
  import { type ArrangeType } from "./arrange";
7
6
  import { type ClipboardDataProducer, type ClipboardPlugin, type DeleteContext, type PasteOptions } from "./clipboard";
8
7
  import { Snap } from "./snap";
@@ -32,6 +31,23 @@ export interface SelectOption extends BaseElementOption {
32
31
  }
33
32
  /** 一次 selection property intent;同一 canonical reference 直接交给各 owner。 */
34
33
  export type SelectedPropertyPatch = Readonly<Record<string, unknown>>;
34
+ /** 应用同步构造的 owner-specific 属性与结构命令;值按原引用交给对应 owner。 */
35
+ export interface SelectCommand {
36
+ readonly ownerChanges?: readonly OwnerPropertyChange[];
37
+ readonly structureChanges?: readonly StructureChange[];
38
+ /**
39
+ * 省略保留当前选择意图;结构提交后过滤已移除或被选中祖先覆盖的元素。
40
+ * 空数组清空选择;仅选择变化不进入 History 或配置通知。
41
+ */
42
+ readonly selectionAfter?: readonly Element[];
43
+ /** false 只关闭本命令的 History;true/省略仍服从 history.enabled。 */
44
+ readonly recordHistory?: boolean;
45
+ /**
46
+ * 有实际 Scene 安装时同步调用一次,位于 Core lifecycle/hooks/observers 及选择安装之后,
47
+ * frame drain、History finish 与配置完成通知之前。不会随 undo/redo 重放;异常直接传播。
48
+ */
49
+ readonly afterInstall?: () => void;
50
+ }
35
51
  /**
36
52
  * 轻量 Editor command/paint surface;交互状态由唯一 controller 拥有。
37
53
  *
@@ -64,6 +80,15 @@ export declare class Select extends Element {
64
80
  get interactionController(): EditorInteractionController;
65
81
  /** 以一次独立操作选择给定元素,并在完成后异步通知 `select:end`。 */
66
82
  select(elements: readonly Element[]): void;
83
+ /** 完成已接受的当前交互,取消未提交的画线草稿;无活动交互时无操作。 */
84
+ finishCurrentInteraction(): void;
85
+ /**
86
+ * 先结束旧交互并稳定几何,再同步调用 createCommand,传入 live selection。
87
+ * 返回本命令 Canvas configured 的净变化,与 History/监听器是否开启无关;不包含旧交互。
88
+ * 返回 undefined 的构造或空/相同值命令是普通 noop。未激活的 Select 不调用构造。
89
+ * 普通选区同一 patch 使用 setProperties;此入口用于 owner-specific 与结构组合操作。
90
+ */
91
+ applyCommand(createCommand: (selection: readonly Element[]) => SelectCommand | undefined): boolean;
67
92
  /**
68
93
  * Groups the live multi-selection. Accepted active Transform work finishes
69
94
  * before the independent Group command; stale pointer continuation is ignored.
@@ -79,7 +104,8 @@ export declare class Select extends Element {
79
104
  /**
80
105
  * Aligns the live selection in world space. Without `referenceRect`, the
81
106
  * current selection-frame AABB is the reference. A supplied world Rect is
82
- * used directly. Distribution keeps strict edge gaps when they are numerically
107
+ * used directly; a reference callback runs once after the previous interaction
108
+ * and pending geometry finish. Distribution keeps strict edge gaps when they are numerically
83
109
  * possible and uses bounded overlap when the selected sizes exceed the reference,
84
110
  * while keeping every selection-frame AABB inside it and preserving order. The
85
111
  * current axis is a noop only when an element cannot fit or no ordered layout is
@@ -87,7 +113,7 @@ export declare class Select extends Element {
87
113
  * History entry; a noop creates neither a transform, History entry, nor configured
88
114
  * change.
89
115
  */
90
- align(type: AlignType, referenceRect?: Readonly<Rect>): void;
116
+ align(type: AlignType, referenceRect?: AlignReference): void;
91
117
  /** 按当前 Layer 与 sibling 顺序排列 live selection。 */
92
118
  arrange(type: ArrangeType): void;
93
119
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fulate/tools",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",