@unofficialbox/box-open-elements 0.31.2 → 0.33.0

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.
@@ -31,6 +31,12 @@ export interface ProcessBox<N = unknown> {
31
31
  /** Show the loop mark in a repeating frame without inferring host semantics from its kind name. */
32
32
  loopMark?: boolean;
33
33
  parentId?: string;
34
+ /** Present (including []) when this host supports variables local to this step/frame. */
35
+ localVariables?: readonly ProcessLocalVariable[];
36
+ /** Explicit opt-in to host-owned local edit requests; absent collections are readonly. */
37
+ localVariablesEditable?: boolean;
38
+ /** Host-owned saved output name, displayed in the variable usage summary. */
39
+ savedResult?: string;
34
40
  }
35
41
  export interface ProcessLine {
36
42
  id: string;
@@ -63,6 +69,29 @@ export interface ProcessVariable {
63
69
  startingValue?: string;
64
70
  problem?: string;
65
71
  }
72
+ export interface ProcessLocalVariable {
73
+ name: string;
74
+ startingValue?: string;
75
+ /** Plain-text host validation; BOE does not evaluate expressions. */
76
+ problem?: string;
77
+ }
78
+ export type ProcessLocalVariableEdit = {
79
+ type: 'add';
80
+ } | {
81
+ type: 'remove';
82
+ index: number;
83
+ name: string;
84
+ } | {
85
+ type: 'rename' | 'starting-value';
86
+ index: number;
87
+ name: string;
88
+ value: string;
89
+ };
90
+ export interface ProcessLocalVariableEditRequest {
91
+ boxId: string;
92
+ path?: NodePath;
93
+ edit: ProcessLocalVariableEdit;
94
+ }
66
95
  /** Host-owned variable edits; the host echoes the updated variables property. */
67
96
  export type ProcessVariableEdit = {
68
97
  type: 'add';
@@ -73,6 +102,10 @@ export type ProcessVariableEdit = {
73
102
  type: 'rename';
74
103
  name: string;
75
104
  value: string;
105
+ } | {
106
+ type: 'description';
107
+ name: string;
108
+ value: string;
76
109
  } | {
77
110
  type: 'scope';
78
111
  name: string;
@@ -141,8 +174,21 @@ export interface ProcessLastRun {
141
174
  /** Keys are projected box IDs, supplied by the host. */
142
175
  steps: Readonly<Record<string, ProcessStepMetrics>>;
143
176
  }
177
+ /** A proposed host-owned connection, also used when reattaching a line. */
178
+ export interface ProcessConnectionProposal {
179
+ readonly from: string;
180
+ readonly to: string;
181
+ /** Exclude this existing line from duplicate/outgoing-limit checks. */
182
+ readonly ignoreLineId?: string;
183
+ }
144
184
  export interface ProcessModel<D = unknown, N = unknown> {
145
185
  project(document: D): ProcessProjection<N>;
186
+ /** Pure synchronous host rule: a nonempty reason rejects preview and commit.
187
+ * Returning null permits an edit request; the host must still accept it. */
188
+ connectionProblem?(document: D, proposal: ProcessConnectionProposal, projection: ProcessProjection<N>): string | null;
189
+ /** Optional synchronous host transaction for Tidy/section semantics.
190
+ * A capable host accepts or refuses; BOE does not fall back to local edits. */
191
+ layoutEdit?(document: D, request: ProcessLayoutEditRequest, projection: ProcessProjection<N>): void;
146
192
  /** Optional host arrangement, used by Tidy up and for missing positions. */
147
193
  arrange?(projection: ProcessProjection<N>): ProcessLayout;
148
194
  /**
@@ -187,15 +233,58 @@ export interface ProcessCheck {
187
233
  boxId?: string;
188
234
  path?: NodePath;
189
235
  }
236
+ /** Insertion intent; explicit centers use canvas world coordinates, not top-left positions. */
237
+ export type ProcessInsertionPlacement = {
238
+ readonly source: 'direction';
239
+ readonly side: ProcessSide;
240
+ } | {
241
+ readonly source: 'next';
242
+ } | {
243
+ readonly source: 'line';
244
+ readonly center: Readonly<{
245
+ x: number;
246
+ y: number;
247
+ }>;
248
+ } | {
249
+ readonly source: 'point';
250
+ readonly center: Readonly<{
251
+ x: number;
252
+ y: number;
253
+ }>;
254
+ };
255
+ /** IDs are scoped by kind; layout notes are separate from projected boxes. */
256
+ export type ProcessSelectionItem = {
257
+ readonly type: 'box';
258
+ readonly id: string;
259
+ } | {
260
+ readonly type: 'line';
261
+ readonly id: string;
262
+ } | {
263
+ readonly type: 'note';
264
+ readonly id: string;
265
+ };
190
266
  export interface ProcessEdit {
191
- type: "add" | "delete" | "duplicate" | "connect" | "disconnect" | "reattach" | "insert" | "reparent";
267
+ type: "add" | "delete" | "duplicate" | "connect" | "disconnect" | "reattach" | "insert" | "reparent" | "reset-line" | "tidy" | "make-section" | "delete-selection";
268
+ /** One atomic mixed deletion; the host owns protected roots, descendants,
269
+ * incident edges and notes. Unsupported hosts must leave it unapplied. */
270
+ selection?: readonly ProcessSelectionItem[];
192
271
  boxId?: string;
193
272
  sourceId?: string;
273
+ /** Duplicate these roots and descendants/internal edges in one host transaction.
274
+ * Plural requests omit sourceId; unsupported hosts must refuse the whole group. */
275
+ sourceIds?: readonly string[];
276
+ /** One world-coordinate translation for every node in a duplicate group. */
277
+ offset?: Readonly<{
278
+ x: number;
279
+ y: number;
280
+ }>;
194
281
  from?: string;
195
282
  to?: string;
196
283
  lineId?: string;
197
284
  kind?: FlowKind;
198
285
  position?: BoxPosition;
286
+ /** Optional for existing hosts; all built-in insertion producers supply intent. */
287
+ placement?: ProcessInsertionPlacement;
199
288
  parentId?: string;
200
289
  fromSide?: ProcessSide;
201
290
  toSide?: ProcessSide;
@@ -208,11 +297,53 @@ export interface ReversibleProcessEdit {
208
297
  redo(): void;
209
298
  /** The already-applied edit's layout, recorded atomically with the document. */
210
299
  layout?: ProcessLayout;
300
+ /** Selection after acceptance; recorded with layout for undo and redo. */
301
+ selectionIds?: readonly string[];
302
+ /** Full mixed selection after acceptance; takes precedence over selectionIds. */
303
+ selection?: readonly ProcessSelectionItem[];
211
304
  }
212
305
  /** Host applies the edit, then calls accept with its inverse and replay. */
213
306
  export interface ProcessEditRequest extends ProcessEdit {
214
307
  accept(command: ReversibleProcessEdit): void;
215
308
  }
309
+ /** Host-owned document/layout operation. Null sourceIds means whole-process Tidy.
310
+ * The host owns eligibility, section membership, route cleanup and related notes. */
311
+ export interface ProcessLayoutEditRequest {
312
+ readonly type: 'tidy' | 'make-section';
313
+ readonly sourceIds: readonly string[] | null;
314
+ readonly title?: string;
315
+ /** Detached current layout; a host may use it to preserve unrelated data. */
316
+ readonly layout: ProcessLayout;
317
+ /** Host has already applied the document edit; full layout is required. */
318
+ accept(command: ReversibleProcessEdit & {
319
+ layout: ProcessLayout;
320
+ }): void;
321
+ refuse(message?: string): void;
322
+ }
323
+ /** Host-owned immutable capture; BOE never serializes the captured graph. */
324
+ export interface ProcessClipboard {
325
+ readonly itemCount: number;
326
+ paste(request: ProcessPasteRequest): void;
327
+ dispose?(): void;
328
+ }
329
+ /** Copy capture is synchronous and once-only. Unsupported hosts leave it unhandled. */
330
+ export interface ProcessCopyRequest {
331
+ /** Full immutable selection, including notes and explicit edges. Hosts own
332
+ * descendant/internal-edge capture and must refuse unsupported mixed capture. */
333
+ readonly selection?: readonly ProcessSelectionItem[];
334
+ readonly sourceIds: readonly string[];
335
+ capture(clipboard: ProcessClipboard): void;
336
+ refuse(message?: string): void;
337
+ }
338
+ /** Host applies one synchronous graph transaction, then accepts it once. */
339
+ export interface ProcessPasteRequest {
340
+ readonly offset: Readonly<{
341
+ x: number;
342
+ y: number;
343
+ }>;
344
+ accept(command: ReversibleProcessEdit): void;
345
+ refuse(message?: string): void;
346
+ }
216
347
  export declare function validateProjection<N>(projection: ProcessProjection<N>): void;
217
348
  /** Deterministic fallback, preserving host-authored positions. */
218
349
  export declare function completeLayout<N>(projection: ProcessProjection<N>, layout: ProcessLayout): ProcessLayout;
@@ -1,7 +1,44 @@
1
1
  import { BaseElement } from "../../core/index.js";
2
2
  import type { NodePath } from "../flow-builder/model.js";
3
3
  import type { ProcessConnection, ProcessVariable, ProcessLoadOptions, ProcessKind, ProcessLastRun, ProcessOutlineItem, ProcessField } from "./model.js";
4
- import { ProcessHistory, type ProcessBox, type ProcessCheck, type ProcessEdit, type ProcessLayout, type ProcessModel, type ProcessProjection } from "./model.js";
4
+ import { ProcessHistory, type ProcessBox, type ProcessCheck, type ProcessEdit, type ProcessSelectionItem, type ProcessCopyRequest, type ProcessLayout, type ProcessModel, type ProcessProjection } from "./model.js";
5
+ /** Source-owned contracts for notifications forwarded through the acceptance queue. */
6
+ export interface ProcessModelerEventDetails {
7
+ 'note-move-request': {
8
+ noteIds: readonly string[];
9
+ notes: readonly NonNullable<ProcessLayout['notes']>[number][];
10
+ };
11
+ 'process-copy-request': ProcessCopyRequest;
12
+ 'process-selection-copy-request': ProcessCopyRequest;
13
+ 'layout-changed': {
14
+ layout: ProcessLayout;
15
+ };
16
+ 'positions-changed': {
17
+ positions: readonly import('./model.js').ProcessPositionSnapshot[];
18
+ version: string | number;
19
+ };
20
+ 'projection-changed': {
21
+ projection: ProcessProjection;
22
+ version: string | number;
23
+ checks: readonly ProcessCheck[];
24
+ };
25
+ 'readable-projection-changed': {
26
+ projection: ProcessProjection;
27
+ version: string | number;
28
+ };
29
+ 'selection-changed': {
30
+ selection?: readonly ProcessSelectionItem[];
31
+ box: ProcessBox | null;
32
+ boxes: readonly ProcessBox[];
33
+ path: NodePath | null;
34
+ } | {
35
+ selection?: readonly ProcessSelectionItem[];
36
+ box: null;
37
+ boxes: never[];
38
+ line: import('./model.js').ProcessLine | null;
39
+ path: null;
40
+ };
41
+ }
5
42
  /** Projects host documents without owning workflow schemas or persistence. */
6
43
  export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends BaseElement {
7
44
  static readonly tagName = "box-process-modeler";
@@ -16,6 +53,9 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
16
53
  private showLastRunValue;
17
54
  private selectedId;
18
55
  private selectedLineId;
56
+ private selectedLineIds;
57
+ private selectedNoteIds;
58
+ private graphSelection;
19
59
  private connecting;
20
60
  private checks;
21
61
  private renderer?;
@@ -23,6 +63,8 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
23
63
  private inspected?;
24
64
  private inspectedId?;
25
65
  private inspectedControls;
66
+ private localEchoRevision;
67
+ private pendingLocalRename?;
26
68
  private historyValue;
27
69
  private viewport;
28
70
  private pointers;
@@ -37,7 +79,14 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
37
79
  private activeDrawer?;
38
80
  private drawerReturn?;
39
81
  private selectedIds;
40
- private clipboardIds;
82
+ private clipboard;
83
+ private clipboardSession;
84
+ private layoutEditSession;
85
+ private acceptanceNotifications;
86
+ private deferredNotifications;
87
+ private notify;
88
+ private flushAcceptanceNotifications;
89
+ private restoringBoxFocus;
41
90
  private selectionToolbarKey;
42
91
  private sectionSequence;
43
92
  private versionValue;
@@ -62,6 +111,9 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
62
111
  private spacePressed;
63
112
  private dropLine?;
64
113
  private paletteDragKind;
114
+ private palettePointer?;
115
+ private suppressPaletteClick;
116
+ private readonly escapePalettePointer;
65
117
  private narrowValue;
66
118
  private suppressClick;
67
119
  private resizeObserver?;
@@ -109,6 +161,10 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
109
161
  }>;
110
162
  load(document: D, options?: ProcessLoadOptions): void;
111
163
  selectMany(ids: readonly string[]): void;
164
+ /** Detached mixed selection. Invalid and duplicate IDs are ignored by selectItems. */
165
+ get selection(): readonly ProcessSelectionItem[];
166
+ selectItems(items: readonly ProcessSelectionItem[]): void;
167
+ private clearMixedSelection;
112
168
  get headingLevel(): number;
113
169
  set headingLevel(value: number);
114
170
  get disableConnections(): boolean;
@@ -148,9 +204,12 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
148
204
  selectLine(id: string | null): void;
149
205
  setValidation(checks: readonly ProcessCheck[]): void;
150
206
  setValidationAtPath(message: string, path: NodePath): void;
207
+ private connectionProblem;
151
208
  requestEdit(edit: ProcessEdit): void;
209
+ private editAcceptance;
152
210
  undo(): void;
153
211
  redo(): void;
212
+ private requestLayoutEdit;
154
213
  private commitLayout;
155
214
  move(id: string, x: number, y: number): void;
156
215
  private emitPositions;
@@ -184,7 +243,13 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
184
243
  arrangeSelection(action: 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom' | 'distribute-horizontal' | 'distribute-vertical'): void;
185
244
  makeSection(title?: string): void;
186
245
  protected setupListeners(): void;
246
+ private clearClipboard;
247
+ private copySelection;
248
+ private pasteClipboard;
249
+ private duplicateBoxes;
187
250
  private onKey;
251
+ private navigateSelection;
252
+ private revealBox;
188
253
  private pointerDown;
189
254
  private distance;
190
255
  private pointerMove;
@@ -194,6 +259,7 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
194
259
  private sideAt;
195
260
  private lineAt;
196
261
  private markDropLine;
262
+ private paintDropLine;
197
263
  private alignedPoint;
198
264
  private openChooser;
199
265
  private nextEdit;
@@ -211,10 +277,20 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
211
277
  private collectChecks;
212
278
  private renderWorld;
213
279
  private place;
280
+ private activatePaletteKind;
281
+ private paletteLineAt;
282
+ private paletteFrameAt;
283
+ private markPaletteDrop;
284
+ private paletteCanvasPoint;
285
+ private movePalettePointer;
286
+ private cancelPalettePointer;
287
+ private finishPalettePointer;
214
288
  private renderPalette;
215
289
  private renderChecks;
216
290
  private renderField;
217
291
  private renderSelection;
292
+ private renderLocalVariables;
293
+ private requestLocalVariableEdit;
218
294
  private renderSelectionToolbar;
219
295
  private updateToolbar;
220
296
  private paintViewport;