@draftably/editor 0.4.0 → 0.6.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.
- package/dist/assets/engine.worker-iJs-dOtM.js +8071 -0
- package/dist/element.js +27 -16
- package/dist/index.js +12154 -11312
- package/dist/types/src/components/scene/EdgeView.d.ts +2 -0
- package/dist/types/src/components/scene/Lifelines.d.ts +4 -3
- package/dist/types/src/components/session-context.d.ts +9 -2
- package/dist/types/src/dsl/compile.d.ts +2 -0
- package/dist/types/src/dsl/sequence-layout.d.ts +87 -0
- package/dist/types/src/dsl/source-edits.d.ts +2 -0
- package/dist/types/src/dsl/syntax.d.ts +8 -2
- package/dist/types/src/dsl/translate.d.ts +1 -1
- package/dist/types/src/editor/internal.d.ts +9 -2
- package/dist/types/src/editor/mount.d.ts +13 -6
- package/dist/types/src/engines/explorer-engine.d.ts +63 -0
- package/dist/types/src/engines/layout/arrange.d.ts +36 -0
- package/dist/types/src/engines/layout/compute.d.ts +7 -0
- package/dist/types/src/engines/layout/forces.d.ts +8 -0
- package/dist/types/src/engines/layout/grid.d.ts +10 -0
- package/dist/types/src/engines/layout/intent.d.ts +14 -0
- package/dist/types/src/engines/layout/layered.d.ts +5 -0
- package/dist/types/src/engines/layout/objective.d.ts +6 -0
- package/dist/types/src/engines/layout/packing.d.ts +7 -0
- package/dist/types/src/engines/layout/report.d.ts +7 -0
- package/dist/types/src/engines/layout/scene.d.ts +53 -0
- package/dist/types/src/engines/layout/seed.d.ts +3 -0
- package/dist/types/src/engines/layout/separation.d.ts +17 -0
- package/dist/types/src/engines/layout/settings.d.ts +6 -0
- package/dist/types/src/engines/layout/topology.d.ts +18 -0
- package/dist/types/src/engines/layout/trees.d.ts +8 -0
- package/dist/types/src/engines/layout/types.d.ts +133 -0
- package/dist/types/src/engines/layout/util.d.ts +19 -0
- package/dist/types/src/engines/layout-engine.d.ts +15 -0
- package/dist/types/src/engines/routing/compute.d.ts +6 -0
- package/dist/types/src/engines/routing/conflicts.d.ts +36 -0
- package/dist/types/src/engines/routing/context.d.ts +37 -0
- package/dist/types/src/engines/routing/cost.d.ts +13 -0
- package/dist/types/src/engines/routing/doglegs.d.ts +16 -0
- package/dist/types/src/engines/routing/find.d.ts +6 -0
- package/dist/types/src/engines/routing/geometry.d.ts +24 -0
- package/dist/types/src/engines/routing/heap.d.ts +20 -0
- package/dist/types/src/engines/routing/improve.d.ts +7 -0
- package/dist/types/src/engines/routing/nudge.d.ts +7 -0
- package/dist/types/src/engines/routing/paths.d.ts +8 -0
- package/dist/types/src/engines/routing/planned.d.ts +7 -0
- package/dist/types/src/engines/routing/ports.d.ts +10 -0
- package/dist/types/src/engines/routing/repair.d.ts +9 -0
- package/dist/types/src/engines/routing/score.d.ts +12 -0
- package/dist/types/src/engines/routing/search.d.ts +16 -0
- package/dist/types/src/engines/routing/settings.d.ts +4 -0
- package/dist/types/src/engines/routing/sidepairs.d.ts +20 -0
- package/dist/types/src/engines/routing/tidy-ports.d.ts +13 -0
- package/dist/types/src/engines/routing/tidy.d.ts +10 -0
- package/dist/types/src/engines/routing/tuning.d.ts +9 -0
- package/dist/types/src/engines/routing/types.d.ts +157 -0
- package/dist/types/src/engines/routing-engine.d.ts +20 -0
- package/dist/types/src/engines/sculpt-engine.d.ts +87 -0
- package/dist/types/src/lib/engine-tasks.d.ts +4 -4
- package/dist/types/src/model/appearance.d.ts +18 -2
- package/dist/types/src/model/edits.d.ts +19 -0
- package/dist/types/src/model/labels.d.ts +23 -0
- package/dist/types/src/model/markers.d.ts +7 -0
- package/dist/types/src/model/note.d.ts +11 -2
- package/dist/types/src/model/routes.d.ts +5 -3
- package/dist/types/src/model/status.d.ts +18 -0
- package/dist/types/src/model/types.d.ts +20 -1
- package/dist/types/src/runtime/color-scheme.d.ts +15 -0
- package/dist/types/src/runtime/host.d.ts +34 -2
- package/dist/types/src/runtime/page-shared.d.ts +1 -1
- package/dist/types/src/runtime/schemes.d.ts +2 -0
- package/dist/types/src/runtime/svg-renderer.d.ts +9 -4
- package/dist/types/src/runtime/types.d.ts +7 -0
- package/dist/types/src/state/active-session.d.ts +9 -2
- package/dist/types/src/state/canvas-commands.d.ts +37 -0
- package/dist/types/src/state/session/actions.d.ts +2 -0
- package/dist/types/src/state/session/emphasis.d.ts +3 -0
- package/dist/types/src/state/session/file-session.d.ts +1 -1
- package/dist/types/src/state/session/index.d.ts +14 -2
- package/dist/types/src/state/session/layout.d.ts +1 -1
- package/dist/types/src/state/session/scene.d.ts +11 -9
- package/dist/types/src/state/session/sculpt.d.ts +1 -1
- package/package.json +1 -1
- package/dist/assets/engine.worker-C6o2x40z.js +0 -7609
|
@@ -4,6 +4,8 @@ export interface EdgeViewProps {
|
|
|
4
4
|
doc: Diagram;
|
|
5
5
|
route: DrawnRoute;
|
|
6
6
|
selected?: boolean;
|
|
7
|
+
/** In a sequence: the selected message answers this one, or this one answers it. */
|
|
8
|
+
paired?: boolean;
|
|
7
9
|
interactive?: boolean;
|
|
8
10
|
/** Its label is being edited in place, so the drawn label hides. */
|
|
9
11
|
editing?: boolean;
|
|
@@ -6,10 +6,11 @@ export declare function Lifelines(props: {
|
|
|
6
6
|
rect: (id: string) => NodeLayout | undefined;
|
|
7
7
|
}): import("solid-js").JSX.Element;
|
|
8
8
|
/**
|
|
9
|
-
* A sequence diagram's panel (`part="panel"`, under the groups)
|
|
10
|
-
* (`part="phases"`, over the groups' column bands)
|
|
9
|
+
* A sequence diagram's panel (`part="panel"`, under the groups), its phase bands
|
|
10
|
+
* (`part="phases"`, over the groups' column bands) or its activation bars (`part="bars"`, over
|
|
11
|
+
* the lifelines), as the SVG export draws them.
|
|
11
12
|
*/
|
|
12
13
|
export declare function SequenceBackdrop(props: {
|
|
13
14
|
doc: Diagram;
|
|
14
|
-
part: 'panel' | 'phases';
|
|
15
|
+
part: 'panel' | 'phases' | 'bars';
|
|
15
16
|
}): import("solid-js").JSX.Element;
|
|
@@ -213,6 +213,8 @@ export declare const useSessionIfAny: () => ({
|
|
|
213
213
|
tail?: import("../model/markers").EndMarker;
|
|
214
214
|
emphasis: boolean;
|
|
215
215
|
dashed: boolean;
|
|
216
|
+
message?: import("../model/markers").MessageKind;
|
|
217
|
+
replyTo?: string;
|
|
216
218
|
status?: import("../model/status").Status;
|
|
217
219
|
spot?: import("../model/status").Spot;
|
|
218
220
|
}[];
|
|
@@ -221,7 +223,7 @@ export declare const useSessionIfAny: () => ({
|
|
|
221
223
|
routingReport: () => import("../engines/routing-engine").RoutingReport;
|
|
222
224
|
blockedRouteIds: () => string[];
|
|
223
225
|
sceneBounds: () => import("../model/types").Rect;
|
|
224
|
-
viewerFrame: ()
|
|
226
|
+
viewerFrame: import("solid-js").Accessor<{
|
|
225
227
|
x: number;
|
|
226
228
|
y: number;
|
|
227
229
|
w: number;
|
|
@@ -265,7 +267,7 @@ export declare const useSessionIfAny: () => ({
|
|
|
265
267
|
h: number;
|
|
266
268
|
};
|
|
267
269
|
notes: import("../model/note").PlacedNote[];
|
|
268
|
-
}
|
|
270
|
+
}>;
|
|
269
271
|
} & {
|
|
270
272
|
states: () => import("../model/appearance").EmphasisState[];
|
|
271
273
|
activeState: () => string | null;
|
|
@@ -274,6 +276,9 @@ export declare const useSessionIfAny: () => ({
|
|
|
274
276
|
showState: (id: string | null) => void;
|
|
275
277
|
stepState: (by: 1 | -1) => boolean;
|
|
276
278
|
drawnDoc: () => import("../model/types").Diagram;
|
|
279
|
+
dark: import("solid-js").Accessor<boolean>;
|
|
280
|
+
setDark: import("solid-js").Setter<boolean>;
|
|
281
|
+
drawnAppearance: () => import("../model/appearance").DiagramAppearance;
|
|
277
282
|
} & {
|
|
278
283
|
tool: import("solid-js").Accessor<import("../state/session/editor").Tool>;
|
|
279
284
|
setToolSignal: import("solid-js").Setter<import("../state/session/editor").Tool>;
|
|
@@ -400,6 +405,8 @@ export declare const useSessionIfAny: () => ({
|
|
|
400
405
|
fitSelectedContainer: () => void;
|
|
401
406
|
toggleCollapse: (id?: string | undefined) => void;
|
|
402
407
|
reverseSelectedEdge: () => void;
|
|
408
|
+
insertEvent: (where: "before" | "after") => string | undefined;
|
|
409
|
+
moveEvent: (by: -1 | 1) => void;
|
|
403
410
|
resetSelectedBends: () => void;
|
|
404
411
|
setLayoutIntent: (role: import("../model/types").IntentRole, id: string | null, placement?: import("../model/types").IntentPlacement) => void;
|
|
405
412
|
markSelectedAs: (role: import("../model/types").IntentRole) => void;
|
|
@@ -49,6 +49,8 @@ export interface SceneEdge extends ModelEdge {
|
|
|
49
49
|
plan?: Planned;
|
|
50
50
|
/** A sequence message: the height of its row; it is drawn straight between lifelines there. */
|
|
51
51
|
row?: number;
|
|
52
|
+
/** A message between distant lanes: the middle of the gap its label sits in. */
|
|
53
|
+
labelX?: number;
|
|
52
54
|
}
|
|
53
55
|
export interface Scene {
|
|
54
56
|
model: Model;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The arithmetic of a sequence diagram's layout, apart from the scene it is applied to: where a
|
|
3
|
+
* label that spans several lanes sits, where each lane stands, and how tall each phase is.
|
|
4
|
+
* `sequenced` in `compile.ts` measures the text and calls these.
|
|
5
|
+
*/
|
|
6
|
+
/** A lower bound on a lane's centre: at least `room` past the centre of lane `from`. */
|
|
7
|
+
export type Hold = {
|
|
8
|
+
from: number;
|
|
9
|
+
room: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The gap a distant message's label sits in, so it crosses no lifeline between its two ends.
|
|
13
|
+
* `base` holds the lane centres that the headers alone give. The choice prefers a gap inside one
|
|
14
|
+
* band, so the label covers no band's border, then a gap that already has room, then the gap
|
|
15
|
+
* nearest the middle of the message, then the left one. Returns the left lane of the gap.
|
|
16
|
+
*/
|
|
17
|
+
export declare function labelSlot(base: number[], a: number, b: number, room: number, across: (lane: number) => boolean): number;
|
|
18
|
+
/**
|
|
19
|
+
* Lane centres from left to right: each lane takes the header gap from its neighbour, or what
|
|
20
|
+
* holds it away from an earlier lane, if that is more.
|
|
21
|
+
*/
|
|
22
|
+
export declare function laneCentres(first: number, gaps: number[], holds: Hold[][]): number[];
|
|
23
|
+
/** What one event draws round its row: how far above it and how far below. */
|
|
24
|
+
export type EventInk = {
|
|
25
|
+
id: string;
|
|
26
|
+
/** The phase that lists the event, if one does. */
|
|
27
|
+
phase?: string;
|
|
28
|
+
/** Height of the label above the line; 0 with no label or for a self-message. */
|
|
29
|
+
label: number;
|
|
30
|
+
/** Ink above and below the row. */
|
|
31
|
+
above: number;
|
|
32
|
+
below: number;
|
|
33
|
+
/** A self-message or a local action: the row after it must clear its ink. */
|
|
34
|
+
tall: boolean;
|
|
35
|
+
/** How far the event runs on down its lifeline, which the next row starts from. */
|
|
36
|
+
drop: number;
|
|
37
|
+
};
|
|
38
|
+
export type RowRules = {
|
|
39
|
+
/** Least distance between two rows. */
|
|
40
|
+
row: number;
|
|
41
|
+
/** Room between a tall event's ink and the next event's ink. */
|
|
42
|
+
clear: number;
|
|
43
|
+
/** Room between a phase band's edge and the ink inside it. */
|
|
44
|
+
pad: number;
|
|
45
|
+
/** Room between two phase bands. */
|
|
46
|
+
gap: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Rows from top to bottom, starting under the headers at `top`. A phase is one block: its band
|
|
50
|
+
* starts `gap` under what came before, holds its events with `pad` round them, and is at least
|
|
51
|
+
* as tall as its title needs. Events outside every phase keep the plain row rule.
|
|
52
|
+
*/
|
|
53
|
+
export declare function eventRows(events: EventInk[], top: number, titleHeight: (phase: string) => number, rules: RowRules): {
|
|
54
|
+
rows: Map<string, number>;
|
|
55
|
+
bands: Map<string, {
|
|
56
|
+
y: number;
|
|
57
|
+
h: number;
|
|
58
|
+
}>;
|
|
59
|
+
end: number;
|
|
60
|
+
};
|
|
61
|
+
/** An event as activation bars read it: who sends to whom, its kind, and what it answers. */
|
|
62
|
+
export type SequenceEvent = {
|
|
63
|
+
id: string;
|
|
64
|
+
source: string;
|
|
65
|
+
target: string;
|
|
66
|
+
message?: string;
|
|
67
|
+
replyTo?: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* A stretch in which a participant is at work on a call: from the event at index `start` to
|
|
71
|
+
* the one at `end`, or a short stub when `end` is unset. `level` is 0, or more when the
|
|
72
|
+
* participant took the call while another of its bars was open.
|
|
73
|
+
*/
|
|
74
|
+
export type ActivationSpan = {
|
|
75
|
+
lane: string;
|
|
76
|
+
call: string;
|
|
77
|
+
start: number;
|
|
78
|
+
end?: number;
|
|
79
|
+
level: number;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* The activation bars of a sequence, read from its calls and their replies. A bar opens where a
|
|
83
|
+
* participant receives a `call` from another and closes at the last reply that answers that
|
|
84
|
+
* call. A call with no reply closes at the participant's next message to another, and without
|
|
85
|
+
* one it is a stub. A call a participant sends to itself opens no bar.
|
|
86
|
+
*/
|
|
87
|
+
export declare function activationSpans(events: SequenceEvent[]): ActivationSpan[];
|
|
@@ -8,6 +8,8 @@ export declare const statements: (doc: SourceDoc) => Statement[];
|
|
|
8
8
|
export declare function statement(command: string, args: Word[], attrs?: Array<[string, Word]>): Statement;
|
|
9
9
|
/** The `node` or `group` declaration of an object. */
|
|
10
10
|
export declare const declaration: (doc: SourceDoc, id: string) => Statement | undefined;
|
|
11
|
+
/** A statement that makes a connection: an `edge`, or a sequence's `action`. */
|
|
12
|
+
export declare const isEdge: (s: Statement) => boolean;
|
|
11
13
|
export declare const edgeStatement: (doc: SourceDoc, id: string) => Statement | undefined;
|
|
12
14
|
export declare const layoutStatement: (doc: SourceDoc, scope: string) => Statement | undefined;
|
|
13
15
|
export declare function getAttr(s: Statement, key: string): Word | undefined;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* keeps every comment and unrelated statement.
|
|
7
7
|
*/
|
|
8
8
|
import { type DiagramAppearance, type Shade } from '../model/appearance';
|
|
9
|
-
import { type EndMarker } from '../model/markers';
|
|
9
|
+
import { type EndMarker, type MessageKind } from '../model/markers';
|
|
10
10
|
import type { Status } from '../model/status';
|
|
11
11
|
import type { ColorKey, LayoutAlgorithmId, LayoutSettings, PortSide, RoutingSettings, ShapeKind } from '../model/types';
|
|
12
12
|
export declare class DslError extends Error {
|
|
@@ -131,9 +131,13 @@ export interface ModelEdge {
|
|
|
131
131
|
tail?: EndMarker;
|
|
132
132
|
/** `constraint=false`: drawn and routed, but layout doesn't rank or order by it. */
|
|
133
133
|
constraint?: false;
|
|
134
|
+
/** Sequence diagrams: `message=`, or `action` for an `action` line. */
|
|
135
|
+
message?: MessageKind;
|
|
136
|
+
/** `answers=`: the earlier message a reply answers. */
|
|
137
|
+
replyTo?: string;
|
|
134
138
|
line: number;
|
|
135
139
|
}
|
|
136
|
-
/** A layout engine run cold over a scope's subtree; see `src/engines/layout-engine.
|
|
140
|
+
/** A layout engine run cold over a scope's subtree; see `src/engines/layout-engine.ts`. */
|
|
137
141
|
export interface EngineRecipe {
|
|
138
142
|
algorithm: LayoutAlgorithmId;
|
|
139
143
|
params: Partial<LayoutSettings>;
|
|
@@ -160,6 +164,8 @@ export interface ModelLayout {
|
|
|
160
164
|
/** With `unit`: the width of one unit, and whether unit numbers run above the first row. */
|
|
161
165
|
unitWidth?: number;
|
|
162
166
|
ruler?: boolean;
|
|
167
|
+
/** `sequence` only: draw a bar on a participant's lifeline while it is at work on a call. */
|
|
168
|
+
activations?: true;
|
|
163
169
|
/** `flow` only: whether a long run of ranks folds into bands. Engines take `fold` as a param. */
|
|
164
170
|
fold: 'auto' | 'never';
|
|
165
171
|
/** Root only: the image shape to aim for; compile tries direction and folding to get closest. */
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* write snaps back when the source is reprojected, so nothing unsaved looks saved. Changes the
|
|
8
8
|
* file cannot express are rejected outright.
|
|
9
9
|
*/
|
|
10
|
-
import type
|
|
10
|
+
import { type DiagramAppearance } from '../model/appearance';
|
|
11
11
|
import type { Diagram } from '../model/types';
|
|
12
12
|
import { type Scene } from './compile';
|
|
13
13
|
import { type SourceDoc } from './syntax';
|
|
@@ -207,6 +207,8 @@ export declare const sessions: WeakMap<object, {
|
|
|
207
207
|
tail?: import("../model/markers").EndMarker;
|
|
208
208
|
emphasis: boolean;
|
|
209
209
|
dashed: boolean;
|
|
210
|
+
message?: import("../model/markers").MessageKind;
|
|
211
|
+
replyTo?: string;
|
|
210
212
|
status?: import("../model/status").Status;
|
|
211
213
|
spot?: import("../model/status").Spot;
|
|
212
214
|
}[];
|
|
@@ -215,7 +217,7 @@ export declare const sessions: WeakMap<object, {
|
|
|
215
217
|
routingReport: () => import("../engines/routing-engine").RoutingReport;
|
|
216
218
|
blockedRouteIds: () => string[];
|
|
217
219
|
sceneBounds: () => import("../model/types").Rect;
|
|
218
|
-
viewerFrame: ()
|
|
220
|
+
viewerFrame: import("solid-js").Accessor<{
|
|
219
221
|
x: number;
|
|
220
222
|
y: number;
|
|
221
223
|
w: number;
|
|
@@ -259,7 +261,7 @@ export declare const sessions: WeakMap<object, {
|
|
|
259
261
|
h: number;
|
|
260
262
|
};
|
|
261
263
|
notes: import("../model/note").PlacedNote[];
|
|
262
|
-
}
|
|
264
|
+
}>;
|
|
263
265
|
} & {
|
|
264
266
|
states: () => import("../model/appearance").EmphasisState[];
|
|
265
267
|
activeState: () => string | null;
|
|
@@ -268,6 +270,9 @@ export declare const sessions: WeakMap<object, {
|
|
|
268
270
|
showState: (id: string | null) => void;
|
|
269
271
|
stepState: (by: 1 | -1) => boolean;
|
|
270
272
|
drawnDoc: () => import("../model/types").Diagram;
|
|
273
|
+
dark: import("solid-js").Accessor<boolean>;
|
|
274
|
+
setDark: import("solid-js").Setter<boolean>;
|
|
275
|
+
drawnAppearance: () => import("../model/appearance").DiagramAppearance;
|
|
271
276
|
} & {
|
|
272
277
|
tool: import("solid-js").Accessor<import("../state/session/editor").Tool>;
|
|
273
278
|
setToolSignal: import("solid-js").Setter<import("../state/session/editor").Tool>;
|
|
@@ -394,6 +399,8 @@ export declare const sessions: WeakMap<object, {
|
|
|
394
399
|
fitSelectedContainer: () => void;
|
|
395
400
|
toggleCollapse: (id?: string | undefined) => void;
|
|
396
401
|
reverseSelectedEdge: () => void;
|
|
402
|
+
insertEvent: (where: "before" | "after") => string | undefined;
|
|
403
|
+
moveEvent: (by: -1 | 1) => void;
|
|
397
404
|
resetSelectedBends: () => void;
|
|
398
405
|
setLayoutIntent: (role: import("../model/types").IntentRole, id: string | null, placement?: import("../model/types").IntentPlacement) => void;
|
|
399
406
|
markSelectedAs: (role: import("../model/types").IntentRole) => void;
|
|
@@ -3,6 +3,7 @@ import { type Camera, type CameraReason, type FrameOptions, type MoveResult } fr
|
|
|
3
3
|
import { type Geometry } from '../runtime/geometry';
|
|
4
4
|
import { type Anchor, type DraftSlot } from '../runtime/anchors';
|
|
5
5
|
import type { Diagnostic } from '../runtime/types';
|
|
6
|
+
import type { EditorUpdate } from '../runtime/host';
|
|
6
7
|
import '../styles/app.css';
|
|
7
8
|
/** The options a host sets on `<draft-editor>`: every mount option but the text and `onChange`. */
|
|
8
9
|
export type EditorOptions = Pick<SessionOptions, 'storageKey' | 'openLink' | 'confirm' | 'onInteract'> & {
|
|
@@ -21,12 +22,21 @@ export interface EditorEvents {
|
|
|
21
22
|
anchors: {
|
|
22
23
|
anchors: readonly Anchor[];
|
|
23
24
|
};
|
|
24
|
-
/**
|
|
25
|
+
/** A source that does not parse (`DRAFT_PARSE`), then slot warnings: an unknown slot, or content larger than its node. */
|
|
25
26
|
diagnostics: {
|
|
26
27
|
revision: number;
|
|
27
28
|
diagnostics: readonly Diagnostic[];
|
|
28
29
|
stale: boolean;
|
|
29
30
|
};
|
|
31
|
+
/** Each update's result, from the first text on. */
|
|
32
|
+
update: EditorUpdateResult;
|
|
33
|
+
/** A link mark was pressed. `preventDefault()` stops the editor opening it. */
|
|
34
|
+
link: {
|
|
35
|
+
itemId: string;
|
|
36
|
+
href: string;
|
|
37
|
+
target: '_blank';
|
|
38
|
+
preventDefault(): void;
|
|
39
|
+
};
|
|
30
40
|
camera: {
|
|
31
41
|
camera: Camera;
|
|
32
42
|
reason: CameraReason;
|
|
@@ -45,11 +55,8 @@ export interface EditorEvents {
|
|
|
45
55
|
preventDefault(): void;
|
|
46
56
|
};
|
|
47
57
|
}
|
|
48
|
-
/** An editor update's outcome
|
|
49
|
-
export type EditorUpdateResult =
|
|
50
|
-
status: 'committed' | 'error' | 'destroyed';
|
|
51
|
-
revision: number;
|
|
52
|
-
};
|
|
58
|
+
/** An editor update's outcome: `EditorUpdate` in `@draftably/runtime/host`. */
|
|
59
|
+
export type EditorUpdateResult = EditorUpdate;
|
|
53
60
|
/** The editor's handle: the viewer's camera, plus editing. */
|
|
54
61
|
export interface MountedEditor {
|
|
55
62
|
/** Resolves once the first text is drawn. */
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Diagram, LayoutAlgorithmId, LayoutIntent } from '../model/types.ts';
|
|
2
|
+
import type { LayoutReport, LayoutScope } from './layout-engine.ts';
|
|
3
|
+
import type { PriorRoute, RouteInput, RoutingResult } from './routing-engine.ts';
|
|
4
|
+
export type ParamValue = string | number | boolean;
|
|
5
|
+
export interface ParamDefinition {
|
|
6
|
+
name: string;
|
|
7
|
+
values: ParamValue[];
|
|
8
|
+
passOnly?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export type ComparisonMode = 'layout' | 'routing';
|
|
11
|
+
export type ComparisonRun = 'rebuild' | 'warm' | 'pass';
|
|
12
|
+
export interface ComparisonConfig {
|
|
13
|
+
mode: ComparisonMode;
|
|
14
|
+
/** Engines, the suggested routing alternatives, or a grid of parameter values. */
|
|
15
|
+
kind: 'algorithms' | 'routes' | 'parameters';
|
|
16
|
+
algorithm: LayoutAlgorithmId;
|
|
17
|
+
algorithms: LayoutAlgorithmId[];
|
|
18
|
+
axisA: string;
|
|
19
|
+
valuesA: string;
|
|
20
|
+
axisB: string;
|
|
21
|
+
valuesB: string;
|
|
22
|
+
run: ComparisonRun;
|
|
23
|
+
maxIterations: number;
|
|
24
|
+
scope: LayoutScope;
|
|
25
|
+
autoPorts: boolean;
|
|
26
|
+
selected: string[];
|
|
27
|
+
containerId?: string;
|
|
28
|
+
fixedIds: string[];
|
|
29
|
+
intent: LayoutIntent;
|
|
30
|
+
viewport: {
|
|
31
|
+
w: number;
|
|
32
|
+
h: number;
|
|
33
|
+
};
|
|
34
|
+
priorRoutes: PriorRoute[];
|
|
35
|
+
}
|
|
36
|
+
export interface CandidateSpec {
|
|
37
|
+
key: string;
|
|
38
|
+
title: string;
|
|
39
|
+
subtitle: string;
|
|
40
|
+
patch: Record<string, ParamValue>;
|
|
41
|
+
}
|
|
42
|
+
export interface CandidateResult {
|
|
43
|
+
spec: CandidateSpec;
|
|
44
|
+
document: Diagram;
|
|
45
|
+
report: LayoutReport | null;
|
|
46
|
+
routing: RoutingResult;
|
|
47
|
+
}
|
|
48
|
+
declare function parseValues(key: string, text: string, mode?: ComparisonMode): ParamValue[];
|
|
49
|
+
declare function effectiveParams(algorithm: LayoutAlgorithmId, run: ComparisonRun): Record<string, ParamDefinition>;
|
|
50
|
+
declare function specs(config: ComparisonConfig): CandidateSpec[];
|
|
51
|
+
/** The scene as the router sees it: collapsed groups stand in for their members. */
|
|
52
|
+
declare function sceneInput(doc: Diagram): RouteInput;
|
|
53
|
+
declare function candidate(baseline: Diagram, spec: CandidateSpec, config: ComparisonConfig): Promise<CandidateResult>;
|
|
54
|
+
export declare const ExplorerLab: {
|
|
55
|
+
layoutParams: Record<string, ParamDefinition>;
|
|
56
|
+
routeParams: Record<string, ParamDefinition>;
|
|
57
|
+
parseValues: typeof parseValues;
|
|
58
|
+
effectiveParams: typeof effectiveParams;
|
|
59
|
+
specs: typeof specs;
|
|
60
|
+
sceneInput: typeof sceneInput;
|
|
61
|
+
candidate: typeof candidate;
|
|
62
|
+
};
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { DiagramEdge, Direction } from '../../model/types.ts';
|
|
2
|
+
import type { Scene } from './scene.ts';
|
|
3
|
+
import type { Centres, Item, LayoutIntent, Point, Rect, Topology } from './types.ts';
|
|
4
|
+
/** A link with an end outside the solve, or between two of its items: `a` and `b` are the items that own its ends. */
|
|
5
|
+
export interface BoundaryLink extends DiagramEdge {
|
|
6
|
+
a: string | null;
|
|
7
|
+
b: string | null;
|
|
8
|
+
}
|
|
9
|
+
/** What one solve of one container's children shares with its force, separation and packing steps. */
|
|
10
|
+
export interface Batch {
|
|
11
|
+
parentId: string | null;
|
|
12
|
+
direction: Direction;
|
|
13
|
+
items: Item[];
|
|
14
|
+
byId: Map<string, Item>;
|
|
15
|
+
t: Topology;
|
|
16
|
+
localIntent: LayoutIntent;
|
|
17
|
+
boundaryLinks: BoundaryLink[];
|
|
18
|
+
/** Hop counts, for the stress solve only. */
|
|
19
|
+
distances: Map<string, Map<string, number>> | null;
|
|
20
|
+
target: Centres | null;
|
|
21
|
+
/** The inside of the parent's frame, or null at the top level. */
|
|
22
|
+
container: Rect | null;
|
|
23
|
+
availableAspect: number;
|
|
24
|
+
/** Each item's centre when the solve began. */
|
|
25
|
+
origin: Centres;
|
|
26
|
+
anchor: number;
|
|
27
|
+
baseCenter: Point;
|
|
28
|
+
pairGap(a: Item, b: Item): number;
|
|
29
|
+
/** Copies the document's positions back onto the items. */
|
|
30
|
+
sync(): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Solves the children of one container: builds the target for the chosen algorithm, runs the
|
|
34
|
+
* force ticks, and keeps the best state by collisions first and energy second.
|
|
35
|
+
*/
|
|
36
|
+
export declare function arrange(scene: Scene, activeIds: string[], parentId: string | null, direction: Direction): Promise<void>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Diagram } from '../../model/types.ts';
|
|
2
|
+
import type { LayoutOptions, LayoutResult } from './types.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Lays out a copy of `input`. A pass moves boxes at most `maxMove` from where they are; a rebuild
|
|
5
|
+
* starts from a seed. Pins, fixed frames and the scope bound what may move.
|
|
6
|
+
*/
|
|
7
|
+
export declare function compute(input: Diagram, opts?: LayoutOptions): Promise<LayoutResult>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Batch } from './arrange.ts';
|
|
2
|
+
import type { Scene } from './scene.ts';
|
|
3
|
+
/** The force on each item for one tick, by ID; `degree` is the weight of the links behind it. */
|
|
4
|
+
export declare function tickForces(scene: Scene, batch: Batch): Map<string, {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
degree: number;
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Centres, Item, Rect, Settings } from './types.ts';
|
|
2
|
+
/** Items in ID order on a grid of even cells, near the wanted aspect. */
|
|
3
|
+
export declare function seedGrid(items: Item[], s: Settings, aspect: number): Centres;
|
|
4
|
+
/** The nearest free cell of a grid round the current centre, closest matches first. */
|
|
5
|
+
export declare function gridTarget(items: Item[], s: Settings, aspect: number): Centres;
|
|
6
|
+
/**
|
|
7
|
+
* Shifts a target onto the drawing: onto the container's corner, the mean of the fixed items, a
|
|
8
|
+
* fixed origin for a rebuild (`canonical`), or else the items' current centre.
|
|
9
|
+
*/
|
|
10
|
+
export declare function alignTarget(map: Centres, items: Item[], container: Rect | null, canonical?: boolean): Centres;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IntentPlacement, IntentRole } from '../../model/types.ts';
|
|
2
|
+
import type { Centres, Item, LayoutIntent } from './types.ts';
|
|
3
|
+
export type Hint = {
|
|
4
|
+
id: string;
|
|
5
|
+
placement: IntentPlacement;
|
|
6
|
+
};
|
|
7
|
+
/** The hints of an intent with their roles, in the order the intent holds them. */
|
|
8
|
+
export declare const hintsOf: (intent: LayoutIntent) => Array<[IntentRole, Hint]>;
|
|
9
|
+
/** Where in the drawing's box each placement puts a shape, as fractions of its free width and height. */
|
|
10
|
+
export declare const placements: Record<IntentPlacement, [number, number]>;
|
|
11
|
+
/** A checked start and end hint. Throws on an unknown shape, an unknown placement, or one shape in both roles. */
|
|
12
|
+
export declare function normalizeIntent(raw?: unknown, validIds?: Set<string> | null): LayoutIntent;
|
|
13
|
+
/** The centre each hinted item should reach, inside the items' current box. */
|
|
14
|
+
export declare function hintTargets(items: Item[], intent: LayoutIntent): Centres;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Centres, Item, Settings, Topology } from './types.ts';
|
|
2
|
+
/** Straight centre-to-centre crossings between a candidate placement's edges. */
|
|
3
|
+
export declare function sketchCrossings(t: Topology, map: Centres): number;
|
|
4
|
+
/** Ranks as columns (or rows), ordered by barycentre sweeps, folded into bands when that fits the aspect better. */
|
|
5
|
+
export declare function layeredTarget(items: Item[], t: Topology, s: Settings, aspect: number): Centres;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Centres, Item, Settings, Topology } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The energy a solve lowers: hint and target errors, link lengths by algorithm, overlap area and
|
|
4
|
+
* forward links that run backwards. `compoundEnergy` adds the cross-boundary links of a compound solve.
|
|
5
|
+
*/
|
|
6
|
+
export declare function objective(items: Item[], t: Topology, s: Settings, distances: Map<string, Map<string, number>> | null, target: Centres | null, compoundEnergy: (() => number) | null): number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Batch } from './arrange.ts';
|
|
2
|
+
import type { Scene } from './scene.ts';
|
|
3
|
+
/**
|
|
4
|
+
* After a rebuild that left overlaps inside a fixed frame: place the movable items one at a time
|
|
5
|
+
* at the free spot nearest their target, in up to four orders. Moves them only when one order fits.
|
|
6
|
+
*/
|
|
7
|
+
export declare function packIntoFrame(scene: Scene, batch: Batch, collisions: number): void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Scene } from './scene.ts';
|
|
2
|
+
import type { LayoutResult, LayoutScope } from './types.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Ends a run: holds each move to the pass limit and rounds it, rejects a pass that added
|
|
5
|
+
* overlaps, writes the settings back, and builds the report.
|
|
6
|
+
*/
|
|
7
|
+
export declare function finish(scene: Scene, scope: LayoutScope, started: number, authoredRootId: string): LayoutResult;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { DiagramGroup, DiagramNode, Direction, NodeLayout } from '../../model/types.ts';
|
|
2
|
+
import type { Diagram, LayoutMetrics, LayoutOptions, Settings, SolverStop, TraceFrame } from './types.ts';
|
|
3
|
+
/** A shape or group ID, or nothing for the top level. */
|
|
4
|
+
export type ParentId = string | null | undefined;
|
|
5
|
+
/** Counters and findings that every solve of one layout run adds to. */
|
|
6
|
+
export interface Run {
|
|
7
|
+
batchCount: number;
|
|
8
|
+
totalIterations: number;
|
|
9
|
+
/** Which hierarchy sweep is running; odd sweeps of a compound layout go top down. */
|
|
10
|
+
hierarchyPhase: number;
|
|
11
|
+
stops: SolverStop[];
|
|
12
|
+
warnings: Set<string>;
|
|
13
|
+
/** Containers whose children a rebuild has already placed from a seed. */
|
|
14
|
+
seeded: Set<string | null>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* One layout run's view of the document: the hierarchy, what is fixed or hidden, and the only
|
|
18
|
+
* ways a solve may move or measure boxes. `doc` is the copy the run changes; `original` keeps the
|
|
19
|
+
* geometry it started from.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createScene(input: Diagram, doc: Diagram, s: Settings, opts: LayoutOptions): {
|
|
22
|
+
doc: Diagram;
|
|
23
|
+
original: Record<string, NodeLayout>;
|
|
24
|
+
nodeIndex: Map<string, number>;
|
|
25
|
+
s: Settings;
|
|
26
|
+
opts: LayoutOptions;
|
|
27
|
+
run: Run;
|
|
28
|
+
aspect: number;
|
|
29
|
+
intent: Partial<Record<import("../../model/types.ts").IntentRole, {
|
|
30
|
+
id: string;
|
|
31
|
+
placement: import("../../model/types.ts").IntentPlacement;
|
|
32
|
+
}>>;
|
|
33
|
+
compound: boolean;
|
|
34
|
+
globalTopology: import("./types.ts").Topology<import("../../model/types.ts").DiagramEdge>;
|
|
35
|
+
groups: Map<string, DiagramGroup>;
|
|
36
|
+
entities: Map<string, DiagramNode | DiagramGroup>;
|
|
37
|
+
pos: Record<string, NodeLayout>;
|
|
38
|
+
child: (id: ParentId) => (DiagramNode | DiagramGroup)[];
|
|
39
|
+
parent: (id: string) => string | undefined;
|
|
40
|
+
inheritedDirection: (id: ParentId) => Direction;
|
|
41
|
+
descend: (id: string) => string[];
|
|
42
|
+
branch: (id: ParentId) => boolean;
|
|
43
|
+
fixed: (id: string) => boolean;
|
|
44
|
+
visible: (id: string) => boolean;
|
|
45
|
+
padded: (id: string) => NodeLayout;
|
|
46
|
+
move: (id: string, dx: number, dy: number) => void;
|
|
47
|
+
resizeAuto: (id: string) => void;
|
|
48
|
+
metrics: () => LayoutMetrics;
|
|
49
|
+
before: LayoutMetrics;
|
|
50
|
+
trace: TraceFrame[];
|
|
51
|
+
captureTrace: (phase: string, force?: boolean) => void;
|
|
52
|
+
};
|
|
53
|
+
export type Scene = ReturnType<typeof createScene>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Batch } from './arrange.ts';
|
|
2
|
+
import type { Scene } from './scene.ts';
|
|
3
|
+
import type { Axis, Item } from './types.ts';
|
|
4
|
+
/**
|
|
5
|
+
* The guarded moves of one solve: a move that keeps an item in its frame and inside the pass's
|
|
6
|
+
* movement limit, the room an item has along one axis, and the pairwise pass that pushes
|
|
7
|
+
* overlapping items apart.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createSeparation(scene: Scene, batch: Batch): {
|
|
10
|
+
constrainedMove: (p: Item, dx: number, dy: number) => void;
|
|
11
|
+
axisCapacity: (p: Item, axis: Axis, sign: number) => number;
|
|
12
|
+
separate: (rounds?: number) => void;
|
|
13
|
+
collisions: () => {
|
|
14
|
+
n: number;
|
|
15
|
+
a: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LayoutSettings } from '../../model/types.ts';
|
|
2
|
+
import type { LayoutAlgorithm } from './types.ts';
|
|
3
|
+
export declare const ALGORITHMS: LayoutAlgorithm[];
|
|
4
|
+
export declare const defaults: LayoutSettings;
|
|
5
|
+
/** Checked settings: defaults under `values`, old names mapped, numbers held to their ranges. */
|
|
6
|
+
export declare function settings(values?: object): LayoutSettings;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { LayoutIntent, Link, Settings, Topology } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The link structure of one solve: neighbours, feedback links, longest-path ranks and connected
|
|
4
|
+
* parts. Links stay as given; a feedback link is only left out of the ranks.
|
|
5
|
+
*/
|
|
6
|
+
export declare function topology<E extends Link>(items: Array<{
|
|
7
|
+
id: string;
|
|
8
|
+
}>, edges: E[], intent?: LayoutIntent): Topology<E>;
|
|
9
|
+
/** Hop counts between every pair of items that links join. */
|
|
10
|
+
export declare function shortestPaths(t: Topology): Map<string, Map<string, number>>;
|
|
11
|
+
export interface Forest {
|
|
12
|
+
roots: string[];
|
|
13
|
+
parent: Map<string, string>;
|
|
14
|
+
kids: Map<string, string[]>;
|
|
15
|
+
depth: Map<string, number>;
|
|
16
|
+
}
|
|
17
|
+
/** A breadth-first spanning forest: from the chosen root, then every source, then the rest. */
|
|
18
|
+
export declare function forest(t: Topology, s: Settings): Forest;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Centres, Item, Link, Settings, Topology } from './types.ts';
|
|
2
|
+
/** A span-based tree: each subtree gets its own width and parents sit over their children. */
|
|
3
|
+
export declare function treeTarget(items: Item[], t: Topology, s: Settings): Centres;
|
|
4
|
+
/** Rings round each root by depth. No solve reaches it: see `Settings`. */
|
|
5
|
+
export declare function radialTarget(items: Item[], t: Topology, s: Settings): Centres;
|
|
6
|
+
export declare function bilateralTarget(items: Item[], t: Topology, s: Settings): Centres | null;
|
|
7
|
+
/** Which way a forward link should run: 1, -1 on the far side of a centred start, 0 across it. */
|
|
8
|
+
export declare function forwardSign(t: Topology, e: Link): number;
|