@draftably/editor 0.0.0-stage → 0.2.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.
Files changed (101) hide show
  1. package/README.md +25 -2
  2. package/dist/LICENSE +21 -0
  3. package/dist/assets/engine.worker-DwN9io_m.js +6856 -0
  4. package/dist/element.js +36 -0
  5. package/dist/index.js +19555 -0
  6. package/dist/types/src/cli/links.d.ts +4 -0
  7. package/dist/types/src/cli/pdf.d.ts +29 -0
  8. package/dist/types/src/cli/png.d.ts +23 -0
  9. package/dist/types/src/cli/svg.d.ts +4 -0
  10. package/dist/types/src/components/Icon.d.ts +14 -0
  11. package/dist/types/src/components/LayoutPreviewBar.d.ts +2 -0
  12. package/dist/types/src/components/canvas/Canvas.d.ts +15 -0
  13. package/dist/types/src/components/canvas/Frame.d.ts +22 -0
  14. package/dist/types/src/components/canvas/InlineEditor.d.ts +2 -0
  15. package/dist/types/src/components/canvas/Notes.d.ts +5 -0
  16. package/dist/types/src/components/canvas/Overlay.d.ts +2 -0
  17. package/dist/types/src/components/canvas/StateBar.d.ts +5 -0
  18. package/dist/types/src/components/canvas/TextHits.d.ts +6 -0
  19. package/dist/types/src/components/canvas/ZoomControls.d.ts +1 -0
  20. package/dist/types/src/components/canvas/text-boxes.d.ts +24 -0
  21. package/dist/types/src/components/controls.d.ts +91 -0
  22. package/dist/types/src/components/scene/EdgeView.d.ts +22 -0
  23. package/dist/types/src/components/scene/GroupView.d.ts +22 -0
  24. package/dist/types/src/components/scene/Lifelines.d.ts +15 -0
  25. package/dist/types/src/components/scene/LinkMark.d.ts +11 -0
  26. package/dist/types/src/components/scene/NodeView.d.ts +18 -0
  27. package/dist/types/src/components/scene/parts.d.ts +50 -0
  28. package/dist/types/src/components/sculpt/BrushDock.d.ts +2 -0
  29. package/dist/types/src/components/sculpt/TimelineDeck.d.ts +2 -0
  30. package/dist/types/src/components/session-context.d.ts +486 -0
  31. package/dist/types/src/dsl/cells.d.ts +91 -0
  32. package/dist/types/src/dsl/channels.d.ts +53 -0
  33. package/dist/types/src/dsl/compile.d.ts +162 -0
  34. package/dist/types/src/dsl/frame.d.ts +38 -0
  35. package/dist/types/src/dsl/lanes.d.ts +23 -0
  36. package/dist/types/src/dsl/layout-edits.d.ts +58 -0
  37. package/dist/types/src/dsl/legend-notes.d.ts +3 -0
  38. package/dist/types/src/dsl/project.d.ts +39 -0
  39. package/dist/types/src/dsl/source-edits.d.ts +37 -0
  40. package/dist/types/src/dsl/syntax.d.ts +317 -0
  41. package/dist/types/src/dsl/translate.d.ts +69 -0
  42. package/dist/types/src/editor/Editor.d.ts +6 -0
  43. package/dist/types/src/editor/element.d.ts +15 -0
  44. package/dist/types/src/editor/mount.d.ts +23 -0
  45. package/dist/types/src/lib/engine-tasks.d.ts +88 -0
  46. package/dist/types/src/lib/font-data.d.ts +9 -0
  47. package/dist/types/src/lib/saved-diagram.d.ts +4 -0
  48. package/dist/types/src/lib/scene-cache.d.ts +4 -0
  49. package/dist/types/src/lib/svg-export.d.ts +15 -0
  50. package/dist/types/src/model/appearance.d.ts +209 -0
  51. package/dist/types/src/model/bounds.d.ts +19 -0
  52. package/dist/types/src/model/camera.d.ts +21 -0
  53. package/dist/types/src/model/colors.d.ts +22 -0
  54. package/dist/types/src/model/document.d.ts +24 -0
  55. package/dist/types/src/model/edits.d.ts +133 -0
  56. package/dist/types/src/model/embed.d.ts +17 -0
  57. package/dist/types/src/model/font-faces.d.ts +24 -0
  58. package/dist/types/src/model/fonts.d.ts +47 -0
  59. package/dist/types/src/model/footnote.d.ts +34 -0
  60. package/dist/types/src/model/frame.d.ts +71 -0
  61. package/dist/types/src/model/geometry.d.ts +29 -0
  62. package/dist/types/src/model/graph.d.ts +53 -0
  63. package/dist/types/src/model/heading.d.ts +38 -0
  64. package/dist/types/src/model/icons.d.ts +2 -0
  65. package/dist/types/src/model/labels.d.ts +88 -0
  66. package/dist/types/src/model/legend.d.ts +25 -0
  67. package/dist/types/src/model/link.d.ts +63 -0
  68. package/dist/types/src/model/markers.d.ts +47 -0
  69. package/dist/types/src/model/note.d.ts +75 -0
  70. package/dist/types/src/model/panels.d.ts +11 -0
  71. package/dist/types/src/model/rich-text.d.ts +24 -0
  72. package/dist/types/src/model/routes.d.ts +170 -0
  73. package/dist/types/src/model/samples.d.ts +11 -0
  74. package/dist/types/src/model/stack.d.ts +8 -0
  75. package/dist/types/src/model/status.d.ts +84 -0
  76. package/dist/types/src/model/styles.d.ts +13 -0
  77. package/dist/types/src/model/surface.d.ts +31 -0
  78. package/dist/types/src/model/types.d.ts +277 -0
  79. package/dist/types/src/runtime/svg-renderer.d.ts +38 -0
  80. package/dist/types/src/server/file-session.d.ts +19 -0
  81. package/dist/types/src/server/workspace.d.ts +21 -0
  82. package/dist/types/src/state/active-session.d.ts +479 -0
  83. package/dist/types/src/state/canvas-commands.d.ts +169 -0
  84. package/dist/types/src/state/canvas-keyboard.d.ts +15 -0
  85. package/dist/types/src/state/keys.d.ts +5 -0
  86. package/dist/types/src/state/links.d.ts +14 -0
  87. package/dist/types/src/state/session/actions.d.ts +77 -0
  88. package/dist/types/src/state/session/canvas-text.d.ts +24 -0
  89. package/dist/types/src/state/session/document.d.ts +84 -0
  90. package/dist/types/src/state/session/editor.d.ts +81 -0
  91. package/dist/types/src/state/session/emphasis.d.ts +11 -0
  92. package/dist/types/src/state/session/file-session.d.ts +98 -0
  93. package/dist/types/src/state/session/index.d.ts +496 -0
  94. package/dist/types/src/state/session/layout.d.ts +79 -0
  95. package/dist/types/src/state/session/pointer.d.ts +19 -0
  96. package/dist/types/src/state/session/routing.d.ts +20 -0
  97. package/dist/types/src/state/session/scene.d.ts +144 -0
  98. package/dist/types/src/state/session/sculpt.d.ts +70 -0
  99. package/dist/types/src/state/toast.d.ts +14 -0
  100. package/dist/types/src/state/workspace.d.ts +3 -0
  101. package/package.json +41 -3
@@ -0,0 +1,317 @@
1
+ /**
2
+ * The `.draft` diagram language: a line-based source format that keeps comments, plus a model
3
+ * parser and a formatter. Adapted from the Meld 0.1 prototype in `reference/meld/original`.
4
+ *
5
+ * Source is kept as a list of lines so that edits can change single statements and formatting
6
+ * keeps every comment and unrelated statement.
7
+ */
8
+ import { type DiagramAppearance, type Shade } from '../model/appearance';
9
+ import { type EndMarker } from '../model/markers';
10
+ import type { Status } from '../model/status';
11
+ import type { ColorKey, LayoutAlgorithmId, LayoutSettings, PortSide, RoutingSettings, ShapeKind } from '../model/types';
12
+ export declare class DslError extends Error {
13
+ readonly line: number;
14
+ readonly column: number;
15
+ constructor(message: string, line?: number, column?: number);
16
+ }
17
+ /** Change marks before `node`, `group` and `edge`, read like a diff, and the status each sets. */
18
+ export declare const MARKS: {
19
+ readonly '+': "added";
20
+ readonly '-': "removed";
21
+ readonly '~': "changed";
22
+ readonly '.': "context";
23
+ };
24
+ export type Mark = keyof typeof MARKS;
25
+ /** A word in a statement. Quoted words are strings; bare words are identifiers and numbers. */
26
+ export interface Word {
27
+ value: string;
28
+ quoted: boolean;
29
+ }
30
+ export interface Statement {
31
+ kind: 'statement';
32
+ command: string;
33
+ /** Change mark written before the command, as in a diff: `+`, `-`, `~` or `.`. */
34
+ mark?: Mark;
35
+ args: Word[];
36
+ attrs: Array<[string, Word]>;
37
+ /** Inline comment including its `#` or `//` marker. */
38
+ comment?: string;
39
+ /** 1-based line in the source this statement was parsed from; 0 when added by an edit. */
40
+ line: number;
41
+ }
42
+ export type SourceLine = {
43
+ kind: 'blank';
44
+ } | {
45
+ kind: 'comment';
46
+ text: string;
47
+ } | Statement;
48
+ export interface SourceDoc {
49
+ lines: SourceLine[];
50
+ }
51
+ export declare const bare: (value: string | number) => Word;
52
+ export declare const quoted: (value: string) => Word;
53
+ /**
54
+ * Split one line into raw tokens, each with its 1-based start column, and a trailing comment.
55
+ * Quoted tokens keep their quotes.
56
+ */
57
+ export declare function tokenize(text: string, line?: number): {
58
+ tokens: string[];
59
+ columns: number[];
60
+ comment?: string;
61
+ };
62
+ /** Read source text into lines. Only lexical errors are reported here. */
63
+ export declare function readSource(source: string): SourceDoc;
64
+ export declare function printStatement(s: Statement): string;
65
+ /**
66
+ * Print source consistently: one space between words, no indentation, at most one blank line in a
67
+ * row, and a final newline. Comments and statement order are kept.
68
+ */
69
+ export declare function printSource(doc: SourceDoc): string;
70
+ /** Format source text. Throws `DslError` for lexical errors; semantics are not checked. */
71
+ export declare const formatSource: (source: string) => string;
72
+ export type DslColor = ColorKey | 'auto';
73
+ export type DslShape = Exclude<ShapeKind, 'icon' | 'image'>;
74
+ /** `cells` lays a group's members edge to edge as one object: a sequence, table or byte layout. */
75
+ export type Algorithm = 'flow' | 'row' | 'column' | 'lanes' | 'sequence' | 'cells';
76
+ export interface ModelObject {
77
+ id: string;
78
+ type: 'node' | 'group';
79
+ label: string;
80
+ parent: string;
81
+ color: DslColor;
82
+ /** Explicit shade; omitted means the default for the object type. */
83
+ shade?: Shade;
84
+ shape: DslShape;
85
+ /** From a change mark; unchanged when omitted. */
86
+ status?: Status;
87
+ /** With `~`: the label before the change. */
88
+ was?: string;
89
+ /** With `~`, nodes only: the shape before the change. */
90
+ wasShape?: DslShape;
91
+ /** With `~`, nodes only: the count before the change; 1 means a single box. */
92
+ wasCount?: number | string;
93
+ /** A link to open from exported drawings, such as a source file or URL. */
94
+ href?: string;
95
+ /**
96
+ * Nodes only: how many things this one box stands for, drawn as a stack with a badge. A short
97
+ * symbol such as `N` or `many` stands for an unknown number.
98
+ */
99
+ count?: number | string;
100
+ /**
101
+ * Groups only: `soft` draws a tint behind the members and `none` draws nothing. Either way the
102
+ * group is not a layout scope: its members are laid out with the nearest framed container's.
103
+ */
104
+ frame?: 'soft' | 'none';
105
+ /** Groups only: `fold=never` keeps the group's chain in one column even when it is much the tallest. */
106
+ fold?: 'never';
107
+ /** Set by the compiler: the soft groups this object sits in below its layout scope, outermost first. */
108
+ soft?: string[];
109
+ /** Cells only: how many columns (or units) of its group's grid the cell covers; `var` for a
110
+ * field of variable length in a byte or bit layout. */
111
+ span?: number | 'var';
112
+ line: number;
113
+ }
114
+ export interface ModelEdge {
115
+ id: string;
116
+ source: string;
117
+ target: string;
118
+ label: string;
119
+ dashed: boolean;
120
+ from: PortSide;
121
+ to: PortSide;
122
+ /** From a change mark; unchanged when omitted. */
123
+ status?: Status;
124
+ /** With `~`: the label before the change. */
125
+ was?: string;
126
+ /** `directed=false`: an undirected connection, drawn without an arrowhead. */
127
+ directed?: false;
128
+ /** `head=`: the mark at the target end, when it isn't the plain arrow. */
129
+ head?: EndMarker;
130
+ /** `tail=`: the mark at the source end, when it has one. */
131
+ tail?: EndMarker;
132
+ /** `constraint=false`: drawn and routed, but layout doesn't rank or order by it. */
133
+ constraint?: false;
134
+ line: number;
135
+ }
136
+ /** A layout engine run cold over a scope's subtree; see `src/engines/layout-engine.js`. */
137
+ export interface EngineRecipe {
138
+ algorithm: LayoutAlgorithmId;
139
+ params: Partial<LayoutSettings>;
140
+ }
141
+ /** Image shapes a drawing can aim for (`fit=`, `vary --fit`): width over height. */
142
+ export declare const FITS: {
143
+ readonly wide: 2;
144
+ readonly slide: 1.78;
145
+ readonly square: 1;
146
+ readonly page: 0.77;
147
+ readonly tall: 0.6;
148
+ };
149
+ export type Fit = keyof typeof FITS;
150
+ export interface ModelLayout {
151
+ scope: string;
152
+ algorithm: Algorithm;
153
+ /** Set when the scope is arranged by a layout engine instead of a built-in recipe. */
154
+ engine?: EngineRecipe;
155
+ direction: 'auto' | 'right' | 'down';
156
+ /** `cells` only: columns in each row of the grid; one row or column without it. */
157
+ columns?: number;
158
+ /** `cells` only: a byte or bit layout, where each column is one unit of the same width. */
159
+ unit?: 'bit' | 'byte';
160
+ /** With `unit`: the width of one unit, and whether unit numbers run above the first row. */
161
+ unitWidth?: number;
162
+ ruler?: boolean;
163
+ /** `flow` only: whether a long run of ranks folds into bands. Engines take `fold` as a param. */
164
+ fold: 'auto' | 'never';
165
+ /** Root only: the image shape to aim for; compile tries direction and folding to get closest. */
166
+ fit?: Fit;
167
+ gap: number;
168
+ minWidth: number;
169
+ minHeight: number;
170
+ line: number;
171
+ }
172
+ export type Hint = {
173
+ type: 'order';
174
+ scope: string;
175
+ ids: string[];
176
+ line: number;
177
+ } | {
178
+ type: 'align';
179
+ axis: 'x' | 'y';
180
+ ids: string[];
181
+ strength: Strength;
182
+ line: number;
183
+ } | {
184
+ type: 'near';
185
+ id: string;
186
+ ref: string;
187
+ side: NearSide;
188
+ gap: number;
189
+ offset: number;
190
+ strength: Strength;
191
+ line: number;
192
+ } | {
193
+ type: 'nudge';
194
+ id: string;
195
+ dx: number;
196
+ dy: number;
197
+ line: number;
198
+ } | {
199
+ type: 'stay';
200
+ id: string;
201
+ x: number;
202
+ y: number;
203
+ weight: number;
204
+ line: number;
205
+ } | {
206
+ type: 'pin';
207
+ id: string;
208
+ x: number;
209
+ y: number;
210
+ line: number;
211
+ }
212
+ /** `height` is unset for `height=auto`: the title's height at that width, as without a size. */
213
+ | {
214
+ type: 'size';
215
+ id: string;
216
+ width: number;
217
+ height?: number;
218
+ line: number;
219
+ };
220
+ export type Strength = 'prefer' | 'required';
221
+ /**
222
+ * What `near id ref` places against: `ref` itself when it is a sibling of `id`, else the group
223
+ * around `ref` that is `id`'s sibling. Undefined when `ref` is not inside one.
224
+ */
225
+ export declare function nearAnchor(by: Map<string, ModelObject>, id: string, ref: string): string | undefined;
226
+ export type NearSide = 'right' | 'left' | 'above' | 'below';
227
+ export type HintType = Hint['type'];
228
+ export declare const POSITION_HINTS: HintType[];
229
+ export interface Model {
230
+ title: string;
231
+ objects: ModelObject[];
232
+ edges: ModelEdge[];
233
+ layouts: ModelLayout[];
234
+ hints: Hint[];
235
+ /** Router settings from a `routing` statement. */
236
+ routing: Partial<RoutingSettings>;
237
+ /** Theme, overrides and color definitions from `theme` and `theme-color` statements. */
238
+ appearance: DiagramAppearance;
239
+ /** Source line of the `theme` statement, and of each `theme-color` by `family:shade`. */
240
+ themeLine: number;
241
+ colorLines: Map<string, number>;
242
+ /** Source line of each `legend` entry, in order. */
243
+ legendLines: number[];
244
+ /** Source line of each `note`, in order. */
245
+ noteLines: number[];
246
+ /** Source line of each `footnote`, in order. */
247
+ footnoteLines: number[];
248
+ /** Source line of each ID an emphasis state lists, by `state:id`. */
249
+ stateLines: Map<string, number>;
250
+ /** Sequence diagrams: `phase` statements, each a run of messages drawn as a row band. */
251
+ phases: Array<{
252
+ id: string;
253
+ label: string;
254
+ ids: string[];
255
+ line: number;
256
+ }>;
257
+ /** Sequence diagrams: the `was-order` statement, the older version's message order. */
258
+ wasOrder?: {
259
+ ids: string[];
260
+ line: number;
261
+ };
262
+ /** Problems that do not stop the file from drawing, such as a `config` key set twice. */
263
+ warnings: {
264
+ code: string;
265
+ message: string;
266
+ line: number;
267
+ }[];
268
+ }
269
+ /** `config` keys and the setting each sets. */
270
+ export declare const CONFIG_KEYS: {
271
+ readonly 'link-base': "linkBase";
272
+ readonly editor: "editor";
273
+ readonly 'strike-removed': "strikeRemoved";
274
+ };
275
+ /** Theme attributes in the file and the override each sets. */
276
+ export declare const THEME_ATTRS: {
277
+ readonly 'padding-x': "paddingX";
278
+ readonly 'padding-y': "paddingY";
279
+ readonly radius: "radius";
280
+ readonly 'title-font': "titleFont";
281
+ readonly 'annotation-font': "annotationFont";
282
+ readonly canvas: "canvas";
283
+ readonly text: "text";
284
+ readonly connection: "connection";
285
+ };
286
+ type Param<K extends string> = {
287
+ key: K;
288
+ min: number;
289
+ max: number;
290
+ } | {
291
+ key: K;
292
+ choices: readonly string[];
293
+ };
294
+ /**
295
+ * Layout engines a file can name. `separate` is left out: it only repairs overlaps in the current
296
+ * drawing, so it cannot be recomputed from the source.
297
+ */
298
+ export declare const ENGINES: readonly LayoutAlgorithmId[];
299
+ /** Engine settings by source attribute. Ranges match the engine's own limits. */
300
+ export declare const ENGINE_PARAMS: Record<string, Param<keyof LayoutSettings>>;
301
+ /** Router settings by source attribute. Ranges match the router's own limits. */
302
+ export declare const ROUTING_PARAMS: Record<string, Param<keyof RoutingSettings>>;
303
+ /** Source attribute for an engine or router setting. */
304
+ export declare const paramAttr: (table: Record<string, Param<string>>, key: string) => string | undefined;
305
+ export declare const isIdentifier: (s: string) => boolean;
306
+ export declare const COLORS: DslColor[];
307
+ export declare const DSL_SHAPES: DslShape[];
308
+ /** Shapes a node's box can draw as it was: a marker's box is a thin cut, so it has no other shape. */
309
+ export declare const PAST_SHAPES: ("text" | "diamond" | "circle" | "box" | "pill")[];
310
+ /** Parse and validate source. Throws `DslError` with a line number for the first problem. */
311
+ export declare function parseModel(source: string | SourceDoc): Model;
312
+ /**
313
+ * The container that lays an object out: its parent, or the nearest framed container above it
314
+ * when its parent is a soft or frameless group. Soft groups are never layout scopes.
315
+ */
316
+ export declare function layoutParent(by: Map<string, ModelObject>, id: string): string;
317
+ export {};
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Translate one committed editor edit into source statements.
3
+ *
4
+ * The editor works on a projected `Diagram`. When an edit is committed, the document before and
5
+ * after it are compared and the supported differences become targeted source changes: model edits
6
+ * become declarations, and moves become relative preferences. Geometry the translator does not
7
+ * write snaps back when the source is reprojected, so nothing unsaved looks saved. Changes the
8
+ * file cannot express are rejected outright.
9
+ */
10
+ import type { DiagramAppearance } from '../model/appearance';
11
+ import type { Diagram } from '../model/types';
12
+ import { type Scene } from './compile';
13
+ import { type SourceDoc } from './syntax';
14
+ export declare class UnsupportedEdit extends Error {
15
+ }
16
+ export interface EditInput {
17
+ source: SourceDoc;
18
+ scene: Scene;
19
+ before: Diagram;
20
+ after: Diagram;
21
+ label: string;
22
+ /** Selected ids when the edit was committed; moves and resizes apply to these. */
23
+ selection: string[];
24
+ }
25
+ export interface EditResult {
26
+ source: SourceDoc;
27
+ /** Editor ids of new objects and connections, mapped to their ids in the source. */
28
+ ids: Map<string, string>;
29
+ /** Short descriptions of saved refinements, for the status message. */
30
+ notes: string[];
31
+ /** Objects a move placed `near` a neighbour, with where they were dropped. */
32
+ drops: Drop[];
33
+ }
34
+ /** A dropped object: where it was let go in the drawing, and that point in its parent. */
35
+ export interface Drop {
36
+ id: string;
37
+ x: number;
38
+ y: number;
39
+ local: {
40
+ x: number;
41
+ y: number;
42
+ };
43
+ }
44
+ /** Replace the `near` of each dropped object with a `stay` at the exact point it was dropped. */
45
+ export declare function keepDropped(source: SourceDoc, drops: Drop[]): void;
46
+ export declare function translateEdit(input: EditInput): EditResult;
47
+ /**
48
+ * Write a diagram appearance as the file's `theme` line and `theme-color` statements. Statements
49
+ * for colors that are no longer defined are removed; the rest are updated in place, so comments
50
+ * next to them stay.
51
+ */
52
+ export declare function writeAppearance(source: SourceDoc, appearance: DiagramAppearance): void;
53
+ /**
54
+ * Write soft `stay` anchors at their current positions for objects around an accepted refinement:
55
+ * every top-level object, and the siblings of each edited object and of its containers. Later
56
+ * additions then move nearby objects instead of rearranging distant ones. Objects that already
57
+ * have a position refinement keep it. Returns the anchored ids.
58
+ */
59
+ export declare function anchorSurroundings(source: SourceDoc, drawn: Scene, edited: string[]): string[];
60
+ /**
61
+ * Let the automatic recipe rearrange a group again: remove soft refinements for everything inside
62
+ * it (pins and sizes stay), and anchor what is around it so the rest of the drawing holds.
63
+ */
64
+ export declare function reflowGroup(source: SourceDoc, scene: Scene, groupId: string): number;
65
+ /**
66
+ * Objects that moved between two compiled versions although no changed statement mentions them
67
+ * (or a container of theirs). Only the outermost moved object of a subtree is listed.
68
+ */
69
+ export declare function movedOutsideEdit(previous: Scene, next: Scene, previousSource: SourceDoc, nextSource: SourceDoc): string[];
@@ -0,0 +1,6 @@
1
+ import { type CanvasProps } from '../components/canvas/Canvas';
2
+ import type { DiagramSession } from '../state/session';
3
+ /** One live diagram: the canvas for `session`. A page can show any number of them. */
4
+ export declare function Editor(props: CanvasProps & {
5
+ session: DiagramSession;
6
+ }): import("solid-js").JSX.Element;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `<draft-editor>`: the editor as a custom element, for any framework or plain HTML. Its `source`
3
+ * attribute or property sets the text; every kept edit fires `draft-change` with the new text.
4
+ * It mounts when added to the page and stops its session when removed.
5
+ */
6
+ import { type MountedEditor } from './mount';
7
+ export interface DraftEditorElement extends HTMLElement {
8
+ source: string;
9
+ readonly editor?: MountedEditor;
10
+ }
11
+ declare global {
12
+ interface HTMLElementTagNameMap {
13
+ 'draft-editor': DraftEditorElement;
14
+ }
15
+ }
@@ -0,0 +1,23 @@
1
+ import { type DiagramSession, type SessionOptions } from '../state/session';
2
+ import '../styles/app.css';
3
+ export interface MountOptions extends SessionOptions {
4
+ /** The `.draft` text to edit. */
5
+ source: string;
6
+ /** Receives the new text after every kept edit, undo and redo. */
7
+ onChange?: (source: string) => void;
8
+ }
9
+ export interface MountedEditor {
10
+ session: DiagramSession;
11
+ /** The text as the editor holds it now. */
12
+ source(): string;
13
+ /** Show text the host changed. Resolves once it is drawn. */
14
+ update(source: string): Promise<void>;
15
+ /** Remove the editor and stop its session. */
16
+ destroy(): void;
17
+ }
18
+ /**
19
+ * Edit one diagram inside `host`: the canvas with selection, dragging, inline editing and its
20
+ * shortcuts. Each edit is written back to the source and reported through `onChange`. Give the
21
+ * host a size; the canvas fills it.
22
+ */
23
+ export declare function mountEditor(host: HTMLElement, options: MountOptions): MountedEditor;
@@ -0,0 +1,88 @@
1
+ import { type CandidateResult, type CandidateSpec, type ComparisonConfig } from '../engines/explorer-engine.js';
2
+ import { type LayoutOptions, type LayoutResult } from '../engines/layout-engine.js';
3
+ import { type Timeline } from '../engines/sculpt-engine.js';
4
+ import { type RouteInput, type RoutingOptions, type RoutingResult } from '../engines/routing-engine.js';
5
+ import { type Scene } from '../dsl/compile';
6
+ import { type ViewState } from '../dsl/project';
7
+ import type { Diagram } from '../model/types';
8
+ export type EngineTask = {
9
+ kind: 'layout';
10
+ doc: Diagram;
11
+ options: LayoutOptions;
12
+ } | {
13
+ kind: 'candidate';
14
+ baseline: Diagram;
15
+ spec: CandidateSpec;
16
+ config: ComparisonConfig;
17
+ } | {
18
+ kind: 'timeline';
19
+ doc: Diagram;
20
+ options: LayoutOptions;
21
+ }
22
+ /** A diagram file variant, compiled exactly as the file would be. */
23
+ | {
24
+ kind: 'source';
25
+ source: string;
26
+ spec: CandidateSpec;
27
+ }
28
+ /** Full-quality routes for a drawing shown meanwhile with quick routes. */
29
+ | {
30
+ kind: 'route';
31
+ input: RouteInput;
32
+ options: RoutingOptions;
33
+ }
34
+ /** A diagram file compiled: laid out, not routed. */
35
+ | {
36
+ kind: 'compile';
37
+ source: string;
38
+ }
39
+ /** A diagram file compiled, projected with the editor's view and routed, as the viewer shows it. */
40
+ | {
41
+ kind: 'scene';
42
+ source: string;
43
+ view: ViewState;
44
+ };
45
+ /** A compiled file and its routes, keyed by the projected document they were drawn for. */
46
+ export interface SceneResult {
47
+ scene: Scene;
48
+ fingerprint: string;
49
+ routing: RoutingResult;
50
+ }
51
+ export type EngineResult<T extends EngineTask> = T extends {
52
+ kind: 'layout';
53
+ } ? LayoutResult : T extends {
54
+ kind: 'candidate' | 'source';
55
+ } ? CandidateResult : T extends {
56
+ kind: 'route';
57
+ } ? RoutingResult : T extends {
58
+ kind: 'scene';
59
+ } ? SceneResult : T extends {
60
+ kind: 'compile';
61
+ } ? Scene : Timeline;
62
+ export declare function runEngineTask(task: EngineTask): Promise<LayoutResult | CandidateResult | Timeline | RoutingResult | SceneResult | Scene>;
63
+ /**
64
+ * Run a short task in one worker that stays up, so frequent work such as recompiling a file after
65
+ * each edit pays no start-up cost. Without workers the task runs on the main thread.
66
+ */
67
+ export declare function runShared<T extends EngineTask>(input: T): Promise<EngineResult<T>>;
68
+ export declare class CancelledError extends Error {
69
+ constructor();
70
+ }
71
+ export interface RunningTask<T> {
72
+ promise: Promise<T>;
73
+ /** Stop the computation. The promise rejects with `CancelledError`. */
74
+ cancel(): void;
75
+ /** `worker`, or `main thread` when workers are unavailable. */
76
+ thread: () => string;
77
+ }
78
+ /** Computations to run at once: one core stays with the page. */
79
+ export declare const poolSize: () => number;
80
+ /** Call `work` for each index up to `count`, with at most `poolSize()` calls going at once. */
81
+ export declare function inPool(count: number, work: (index: number) => Promise<void>): Promise<void>;
82
+ /**
83
+ * Run an engine computation in a worker. If the browser blocks workers, the same computation
84
+ * runs on the main thread instead.
85
+ */
86
+ export declare function startEngineTask<T extends EngineTask>(input: T, { timeout }?: {
87
+ timeout?: number;
88
+ }): RunningTask<EngineResult<T>>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The bundled diagram fonts as data URLs, for SVG exports that must render without the app.
3
+ * The browser loads this module only when exporting; the CLI bundles it.
4
+ */
5
+ import type { ResolvedAppearance } from '../model/appearance';
6
+ /** `@font-face` rules for the faces an appearance draws with. */
7
+ export declare function fontFaceCss(look: ResolvedAppearance): string;
8
+ /** Make the bundled faces available to the page, so the canvas draws with measured fonts. */
9
+ export declare function registerFonts(): void;
@@ -0,0 +1,4 @@
1
+ /** Where the editor keeps the browser's diagram. The site reads it too: same origin. */
2
+ export declare const STORAGE_KEY = "diagram-studio-v5";
3
+ /** The title of the diagram kept in this browser, if there is one. */
4
+ export declare function savedTitle(): string;
@@ -0,0 +1,4 @@
1
+ /** The compiled file stored for `source` by this build, if any. */
2
+ export declare function cachedScene<T>(source: string): Promise<T | undefined>;
3
+ /** Store the compiled file for `source`, keeping the most recently stored few. */
4
+ export declare function cacheScene(source: string, value: unknown): Promise<void>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Deep-copy an SVG subtree with computed styles inlined and editor-only parts removed. An object
3
+ * with a link (`data-href`) is wrapped in `<a>`, its target written by `href`. The source element
4
+ * must be attached to the document.
5
+ */
6
+ export declare function materializeSvg<T extends SVGElement>(original: T, href?: (href: string) => string): T;
7
+ export declare const serializeSvg: (node: Node) => string;
8
+ export declare function createSvgElement<K extends keyof SVGElementTagNameMap>(tag: K, attrs?: Record<string, string | number>): SVGElementTagNameMap[K];
9
+ export declare const escapeXml: (value: unknown) => string;
10
+ export declare function downloadBlob(blob: Blob, name: string): void;
11
+ /** A download name from the diagram's title: `My plan` → `my-plan.svg`. */
12
+ export declare function fileName(title: string, extension: string): string;
13
+ export declare const downloadText: (text: string, name: string, type: string) => void;
14
+ /** Rasterize an SVG string at `scale` (2× unless given), within browser canvas limits. */
15
+ export declare function svgToPng(svg: string, scale?: number): Promise<Blob>;