@draftably/runtime 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.
Files changed (75) hide show
  1. package/README.md +1 -1
  2. package/dist/assets/render.worker-CDf818A5.js +9040 -0
  3. package/dist/compile-CvMiDEcR.js +7837 -0
  4. package/dist/element.js +12 -12
  5. package/dist/graph.js +1 -1
  6. package/dist/host.js +12 -4
  7. package/dist/index.js +2 -2
  8. package/dist/render-DU-eRw6k.js +1250 -0
  9. package/dist/types/src/dsl/compile.d.ts +2 -0
  10. package/dist/types/src/dsl/sequence-layout.d.ts +87 -0
  11. package/dist/types/src/dsl/syntax.d.ts +8 -2
  12. package/dist/types/src/engines/layout/arrange.d.ts +36 -0
  13. package/dist/types/src/engines/layout/compute.d.ts +7 -0
  14. package/dist/types/src/engines/layout/forces.d.ts +8 -0
  15. package/dist/types/src/engines/layout/grid.d.ts +10 -0
  16. package/dist/types/src/engines/layout/intent.d.ts +14 -0
  17. package/dist/types/src/engines/layout/layered.d.ts +5 -0
  18. package/dist/types/src/engines/layout/objective.d.ts +6 -0
  19. package/dist/types/src/engines/layout/packing.d.ts +7 -0
  20. package/dist/types/src/engines/layout/report.d.ts +7 -0
  21. package/dist/types/src/engines/layout/scene.d.ts +53 -0
  22. package/dist/types/src/engines/layout/seed.d.ts +3 -0
  23. package/dist/types/src/engines/layout/separation.d.ts +17 -0
  24. package/dist/types/src/engines/layout/settings.d.ts +6 -0
  25. package/dist/types/src/engines/layout/topology.d.ts +18 -0
  26. package/dist/types/src/engines/layout/trees.d.ts +8 -0
  27. package/dist/types/src/engines/layout/types.d.ts +133 -0
  28. package/dist/types/src/engines/layout/util.d.ts +19 -0
  29. package/dist/types/src/engines/layout-engine.d.ts +14 -119
  30. package/dist/types/src/engines/routing/compute.d.ts +6 -0
  31. package/dist/types/src/engines/routing/conflicts.d.ts +36 -0
  32. package/dist/types/src/engines/routing/context.d.ts +37 -0
  33. package/dist/types/src/engines/routing/cost.d.ts +13 -0
  34. package/dist/types/src/engines/routing/doglegs.d.ts +16 -0
  35. package/dist/types/src/engines/routing/find.d.ts +6 -0
  36. package/dist/types/src/engines/routing/geometry.d.ts +24 -0
  37. package/dist/types/src/engines/routing/heap.d.ts +20 -0
  38. package/dist/types/src/engines/routing/improve.d.ts +7 -0
  39. package/dist/types/src/engines/routing/nudge.d.ts +7 -0
  40. package/dist/types/src/engines/routing/paths.d.ts +8 -0
  41. package/dist/types/src/engines/routing/planned.d.ts +7 -0
  42. package/dist/types/src/engines/routing/ports.d.ts +10 -0
  43. package/dist/types/src/engines/routing/repair.d.ts +9 -0
  44. package/dist/types/src/engines/routing/score.d.ts +12 -0
  45. package/dist/types/src/engines/routing/search.d.ts +16 -0
  46. package/dist/types/src/engines/routing/settings.d.ts +4 -0
  47. package/dist/types/src/engines/routing/sidepairs.d.ts +20 -0
  48. package/dist/types/src/engines/routing/tidy-ports.d.ts +13 -0
  49. package/dist/types/src/engines/routing/tidy.d.ts +10 -0
  50. package/dist/types/src/engines/routing/tuning.d.ts +9 -0
  51. package/dist/types/src/engines/routing/types.d.ts +157 -0
  52. package/dist/types/src/engines/routing-engine.d.ts +19 -107
  53. package/dist/types/src/model/appearance.d.ts +18 -2
  54. package/dist/types/src/model/labels.d.ts +23 -0
  55. package/dist/types/src/model/markers.d.ts +7 -0
  56. package/dist/types/src/model/note.d.ts +11 -2
  57. package/dist/types/src/model/routes.d.ts +2 -0
  58. package/dist/types/src/model/status.d.ts +18 -0
  59. package/dist/types/src/model/types.d.ts +20 -1
  60. package/dist/types/src/runtime/color-scheme.d.ts +15 -0
  61. package/dist/types/src/runtime/host.d.ts +34 -2
  62. package/dist/types/src/runtime/page-shared.d.ts +1 -1
  63. package/dist/types/src/runtime/schemes.d.ts +2 -0
  64. package/dist/types/src/runtime/svg-renderer.d.ts +9 -4
  65. package/dist/types/src/runtime/types.d.ts +7 -0
  66. package/dist/version-D7YCY2pU.js +4 -0
  67. package/dist/viewer.css +14 -8
  68. package/dist/viewer.js +474 -453
  69. package/package.json +1 -1
  70. package/dist/assets/render.worker-BXjS76Gy.js +0 -8485
  71. package/dist/compile-C2lvlbqE.js +0 -7369
  72. package/dist/render-CFWEEKPT.js +0 -1160
  73. package/dist/types/src/engines/explorer-engine.d.ts +0 -67
  74. package/dist/types/src/engines/sculpt-engine.d.ts +0 -71
  75. package/dist/version-CKs2Vl8m.js +0 -4
@@ -62,6 +62,12 @@ export interface NodeLabel {
62
62
  export declare function nodeLabel(doc: Diagram, id: string, title: string, r: Rect): NodeLabel;
63
63
  /** Bounds of a shape together with its label. */
64
64
  export declare function visualBounds(doc: Diagram, id: string, title: string, r: Rect): Rect;
65
+ /** Text width a sequence phase's label wraps to, so a long one does not push the lanes right. */
66
+ export declare const PHASE_WRAP = 96;
67
+ /** Inset of a phase label from its band's top left corner. */
68
+ export declare const PHASE_TAB = 8;
69
+ /** A phase label's lines, in the annotation type. */
70
+ export declare const phaseLabelLines: (label: string, r: ResolvedAppearance) => string[];
65
71
  /** Text width a sequence message's label wraps to; the gap between participants follows it. */
66
72
  export declare const MESSAGE_WRAP = 168;
67
73
  /**
@@ -93,6 +99,23 @@ export declare function edgeLabelSize(label: string, r?: ResolvedAppearance, mes
93
99
  w: number;
94
100
  h: number;
95
101
  };
102
+ /**
103
+ * An activation bar: its width, how far a nested bar steps to the right, how far it runs past
104
+ * its first and last rows, and the length of a bar whose call gets no reply.
105
+ */
106
+ export declare const ACTIVATION: {
107
+ w: number;
108
+ step: number;
109
+ over: number;
110
+ stub: number;
111
+ };
112
+ /** Room between a local action's label and its box, on each side. */
113
+ export declare const ACTION_PAD = 5;
114
+ /** The box of a local action: its label and `ACTION_PAD` round it, centred on the lifeline. */
115
+ export declare function actionSize(label: string, r: ResolvedAppearance): {
116
+ w: number;
117
+ h: number;
118
+ };
96
119
  /**
97
120
  * What a self-message draws, measured from where its row meets the lifeline: how far right, how
98
121
  * far above the row and how far below it.
@@ -30,10 +30,17 @@ export declare const markerBox: (kind: Exclude<EndMarker, "none">, tail: boolean
30
30
  };
31
31
  /** The fill a marker takes on this line and surface. */
32
32
  export declare function markerFill(kind: Exclude<EndMarker, 'none'>, ink: string, surface: string): string;
33
+ /**
34
+ * What `message=` accepts on a sequence message, plus `action`, which an `action` line makes.
35
+ * Each says what the author means; none is read from a line's style.
36
+ */
37
+ export declare const MESSAGE_KINDS: readonly ["interaction", "call", "send", "reply", "outcome"];
38
+ export type MessageKind = (typeof MESSAGE_KINDS)[number] | 'action';
33
39
  type Ends = {
34
40
  directed?: boolean;
35
41
  head?: EndMarker;
36
42
  tail?: EndMarker;
43
+ message?: MessageKind;
37
44
  };
38
45
  /** An undirected edge has no marks, whatever else it holds. */
39
46
  export declare const headOf: (e: Ends) => EndMarker;
@@ -46,13 +46,22 @@ export declare function noteBox(look: ResolvedAppearance, note: Note): PlacedNot
46
46
  * Spots in a sequence's side margins, by index in `notes`, for notes on the messages in `rows`.
47
47
  * `left` and `right` are the margins' inner edges and `top` the highest a note goes. A note is
48
48
  * level with its row, or pushed down clear of the note above it. The panel grows round these, so
49
- * no note here can cover the drawing.
49
+ * no note here can cover the drawing. A note on a message in a phase stays inside that phase's
50
+ * band (`bands`, by message), which `marginNoteRoom` makes tall enough for its notes.
50
51
  */
51
52
  export declare function marginNotes(look: ResolvedAppearance, notes: readonly Note[], rows: ReadonlyMap<string, number>, { left, right, top }: {
52
53
  left: number;
53
54
  right: number;
54
55
  top: number;
55
- }): (Rect | null)[];
56
+ }, bands?: ReadonlyMap<string, {
57
+ y: number;
58
+ h: number;
59
+ }>): (Rect | null)[];
60
+ /**
61
+ * The height a phase band needs for the margin notes on its messages (`ids`): the taller of its
62
+ * two sides, each a stack of its notes.
63
+ */
64
+ export declare function marginNoteRoom(look: ResolvedAppearance, notes: readonly Note[], ids: string[]): number;
56
65
  /**
57
66
  * Place every anchored note beside its object or message, clear of shapes, group borders, lines
58
67
  * and earlier notes when a nearby spot allows it. Frame notes, and notes whose object is not drawn,
@@ -132,6 +132,8 @@ export declare function routeInput(doc: Diagram, vg: VisibleGraph, all: Map<stri
132
132
  tail?: import("./markers.js").EndMarker;
133
133
  emphasis: boolean;
134
134
  dashed: boolean;
135
+ message?: import("./markers.js").MessageKind;
136
+ replyTo?: string;
135
137
  status?: import("./status.js").Status;
136
138
  spot?: import("./status.js").Spot;
137
139
  }[];
@@ -82,3 +82,21 @@ export declare function withState(doc: Diagram, id: string): Diagram;
82
82
  export declare function usedStatuses(doc: Diagram): StatusCount[];
83
83
  /** The color key's rows: a diff draws no family colors, so it lists only its statuses. */
84
84
  export declare const drawnLegend: (doc: Diagram) => LegendEntry[];
85
+ /** What every sequence says under its drawing. */
86
+ export declare const SEQUENCE_CAPTION = "Rows show order, not elapsed time.";
87
+ /**
88
+ * The events that belong with one event of a sequence: a message, the reply that answers it,
89
+ * and the message a reply answers. Only pairs the file states, never a guess from direction.
90
+ */
91
+ export declare function replyPair(doc: Diagram, id: string): string[];
92
+ /**
93
+ * A sequence in words, for a reader who cannot see it: the participants, then each event in
94
+ * order with its kind. An exported SVG carries it as its description unless the host gives one.
95
+ */
96
+ export declare function sequenceDescription(doc: Diagram): string | undefined;
97
+ /**
98
+ * The key a sequence draws for its kinds of message: one row for each mark in use, so a reader
99
+ * never has to guess what a solid head or a box means. Nothing unless a message has a kind. A
100
+ * plain message and a shown result draw the same arrow, so they share a row.
101
+ */
102
+ export declare function messageKey(doc: Diagram): LegendEntry[];
@@ -13,7 +13,7 @@ export type PortSide = Side | 'auto';
13
13
  export type Direction = 'RIGHT' | 'DOWN';
14
14
  export type Theme = 'light' | 'dark';
15
15
  import type { DiagramAppearance, Shade } from './appearance.js';
16
- import type { EndMarker } from './markers.js';
16
+ import type { EndMarker, MessageKind } from './markers.js';
17
17
  import type { Spot, Status } from './status.js';
18
18
  export type ShapeKind = 'box' | 'pill' | 'circle' | 'diamond' | 'text' | 'icon' | 'image'
19
19
  /** A seam between two cells of a `cells` group. */
@@ -70,6 +70,13 @@ export interface DiagramEdge {
70
70
  tail?: EndMarker;
71
71
  emphasis: boolean;
72
72
  dashed: boolean;
73
+ /**
74
+ * A sequence message's meaning, from `message=`, or `action` for work one participant does
75
+ * (an `action` line; `from` and `to` are that participant). Unset for a plain message.
76
+ */
77
+ message?: MessageKind;
78
+ /** With `message: 'reply'`: the earlier message this one answers, from `answers=`. */
79
+ replyTo?: string;
73
80
  /** How it differs between two versions of the diagram. */
74
81
  status?: Status;
75
82
  /** How the drawn emphasis state treats it; see `withState`. */
@@ -93,6 +100,8 @@ export interface EdgeLayout {
93
100
  toOffset?: number;
94
101
  /** A sequence message: drawn straight between the two lifelines at this height, not routed. */
95
102
  row?: number;
103
+ /** A message between distant lanes: the middle of the gap between lifelines its label sits in. */
104
+ labelX?: number;
96
105
  /**
97
106
  * Set by the compiler for a forward line in a `flow` scope: its route planned from the ranks.
98
107
  * The quick router takes it as it is when it clears every box.
@@ -274,8 +283,18 @@ export interface SequenceLayout {
274
283
  rows: Record<string, number>;
275
284
  phases: SequencePhase[];
276
285
  grow: number;
286
+ activations?: Activation[];
277
287
  };
288
+ /** With `activations=on`: the bars on the lifelines of participants at work on a call. */
289
+ activations?: Activation[];
290
+ /** The `activations=on` switch itself, which the Inspector turns on and off. */
291
+ bars?: true;
278
292
  }
293
+ /** One activation bar: its participant, the call that opened it, and its box. */
294
+ export type Activation = Rect & {
295
+ node: string;
296
+ call: string;
297
+ };
279
298
  export type SequencePhase = {
280
299
  id: string;
281
300
  label: string;
@@ -0,0 +1,15 @@
1
+ /** Watches one host's scheme. `check` reads it again now; `stop` ends the watch. */
2
+ export interface SchemeWatch {
3
+ check(): void;
4
+ stop(): void;
5
+ }
6
+ /**
7
+ * Calls `onChange(dark)` now and whenever the scheme in `host` changes: an element, or a shadow
8
+ * root, whose children inherit the element's scheme. A hidden probe in `host` has a `light-dark()`
9
+ * color, so a scheme change anywhere above it (a class flip on the page, a style) starts a
10
+ * transition there; the media query covers a change of system setting under `light dark`. A
11
+ * transition cannot run while the host has no box (a hidden tab, a closed `<details>`, a detached
12
+ * mount), so a resize observer on the host reads the scheme again when it gets one. Callers also
13
+ * call `check` after each commit.
14
+ */
15
+ export declare function watchColorScheme(host: Element | ShadowRoot, onChange: (dark: boolean) => void): SchemeWatch;
@@ -3,6 +3,7 @@
3
3
  * packages loop over `HOST_EVENTS`, so a new event adds no lines to any of them.
4
4
  * This module has no side effects and no runtime imports.
5
5
  */
6
+ import type { RenderFailure } from './types.js';
6
7
  import type { UpdateResult, ViewerEvents } from './viewer.js';
7
8
  export type { Camera, CameraReason, FrameOptions, MoveResult } from './camera.js';
8
9
  export type { Box, EdgeOut, Geometry, PlacedBox } from './geometry.js';
@@ -10,8 +11,11 @@ export type { Anchor, DraftSlot } from './anchors.js';
10
11
  export interface HostEvents {
11
12
  /** After each commit, after the marked children change, and with `[]` before destroy. */
12
13
  anchors: ViewerEvents['anchors'];
13
- /** Each update's result: committed, error or a cancellation. */
14
- update: UpdateResult;
14
+ /**
15
+ * Each update's result, from the first source on: committed, error or a cancellation. The
16
+ * editor's commit has no `value` or `diagnostics` (see `EditorUpdate`).
17
+ */
18
+ update: UpdateResult | EditorUpdate;
15
19
  render: ViewerEvents['render'];
16
20
  diagnostics: ViewerEvents['diagnostics'];
17
21
  camera: ViewerEvents['camera'];
@@ -30,11 +34,39 @@ export interface HostEvents {
30
34
  source: string;
31
35
  };
32
36
  }
37
+ /**
38
+ * `<draft-editor>`'s update. The editor draws in its own session, not as one SVG, so a commit
39
+ * has no `value` and no `diagnostics`: the `diagnostics` event has them. A source that does not
40
+ * parse is an `error` with a `DRAFT_PARSE` diagnostic; the editor keeps the text and shows it.
41
+ */
42
+ export type EditorUpdate = {
43
+ status: 'committed';
44
+ revision: number;
45
+ value?: never;
46
+ diagnostics?: never;
47
+ } | {
48
+ status: 'error';
49
+ revision: number;
50
+ error: RenderFailure;
51
+ } | {
52
+ status: 'destroyed';
53
+ revision: number;
54
+ };
33
55
  export type HostEventName = keyof HostEvents;
34
56
  /** Every event, in one list. Each element dispatches these as bubbling `draft-<name>` events. */
35
57
  export declare const HOST_EVENTS: readonly ["anchors", "update", "render", "diagnostics", "camera", "itemactivate", "link", "contextmenu", "select", "change"];
36
58
  /** Events a host can cancel with `preventDefault()`. */
59
+ export type CancelableEventName = 'link' | 'contextmenu';
37
60
  export declare const CANCELABLE_EVENTS: readonly HostEventName[];
61
+ /**
62
+ * What a framework event prop receives: the event's `detail`, and on a cancelable event a
63
+ * `preventDefault()` that cancels the DOM event, so `onLink={e => e.preventDefault()}` works.
64
+ */
65
+ export type HostEventDetail<K extends HostEventName> = K extends CancelableEventName ? HostEvents[K] & {
66
+ preventDefault(): void;
67
+ } : HostEvents[K];
68
+ /** The value a framework event prop receives for a `draft-<name>` event. */
69
+ export declare function hostDetail(event: Event): unknown;
38
70
  export type DraftEventMap = {
39
71
  [K in HostEventName as `draft-${K}`]: CustomEvent<HostEvents[K]>;
40
72
  };
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { RenderOptions, RenderResult } from './types.js';
6
6
  /** Names the worker and the usual fix, so "worker failed" is not a dead end. */
7
- export declare const WORKER_HELP = "The worker is the module next to @draftably/runtime's viewer. With Vite, add optimizeDeps: { exclude: ['@draftably/runtime', '@draftably/editor'] } to vite.config.";
7
+ export declare const WORKER_HELP = "The worker is the module next to @draftably/runtime's viewer. With Vite 5\u20137, add optimizeDeps: { exclude: ['@draftably/runtime', '@draftably/editor'] } to vite.config.";
8
8
  /**
9
9
  * Render in the page's worker pool. Jobs queue on the main thread; an aborted job leaves the
10
10
  * queue before a worker sees it. A job that runs past `timeoutMs` stops its worker only.
@@ -0,0 +1,2 @@
1
+ /** Both drawings as one, or null when they differ in more than color. */
2
+ export declare function mergeSchemes(light: string, dark: string): string | null;
@@ -3,6 +3,7 @@
3
3
  * same appearance, shapes and title wrapping as the canvas and embeds the fonts it uses.
4
4
  */
5
5
  import { type ResolvedAppearance } from '../model/appearance.js';
6
+ import { PHASE_TAB } from '../model/labels.js';
6
7
  import { computeRoutes } from '../model/routes.js';
7
8
  import type { Diagram, Rect } from '../model/types.js';
8
9
  /** How an object's `href` is written into the file; as written unless the caller says. */
@@ -26,21 +27,25 @@ export interface SvgOptions {
26
27
  rects: Map<string, Rect>;
27
28
  routes: Route[];
28
29
  }) => void;
30
+ /**
31
+ * The routes `onDrawn` gave for this document, so drawing it again in other colors routes
32
+ * nothing again (not for compare or states).
33
+ */
34
+ routes?: Route[];
29
35
  }
30
36
  export declare class SvgLimitError extends Error {
31
37
  }
32
- type Route = ReturnType<typeof computeRoutes>['routes'][number];
38
+ export type Route = ReturnType<typeof computeRoutes>['routes'][number];
33
39
  /**
34
40
  * A sequence diagram's panel, a light surface with a border that bounds the exchange, and a row
35
41
  * band for each phase with its label in a tab at the left edge. Drawn under everything else.
36
42
  */
37
43
  export declare function sequenceBackdrop(doc: Diagram, look: ResolvedAppearance): {
38
44
  panel: string[];
45
+ bars: string[];
39
46
  phases: string[];
40
47
  };
41
- /** Inset of a phase label from its band's top left corner. */
42
- export declare const PHASE_TAB = 8;
48
+ export { PHASE_TAB };
43
49
  /** A thin stripe across the top of a box, inside its rounded corners. */
44
50
  export declare function accentPath(r: Rect, radius: number): string;
45
51
  export declare function renderSvg(doc: Diagram, opts?: SvgOptions): string;
46
- export {};
@@ -49,6 +49,13 @@ export interface CommonRenderOptions {
49
49
  sourceId?: string;
50
50
  signal?: AbortSignal;
51
51
  limits?: Partial<RenderLimits>;
52
+ /**
53
+ * `light` (default) draws the file's own colors. `dark` draws a file without a `theme` line in
54
+ * the default theme's dark variant. `auto` writes both as `light-dark()` colors, so the page's
55
+ * `color-scheme` picks one; the viewer and `<draft-diagram>` use it. A file's own theme line
56
+ * always wins.
57
+ */
58
+ colorScheme?: 'light' | 'dark' | 'auto';
52
59
  }
53
60
  export type RenderOptions = CommonRenderOptions & ({
54
61
  target?: 'image';
@@ -0,0 +1,4 @@
1
+ const n = "0.6.0", o = n;
2
+ export {
3
+ o as r
4
+ };
package/dist/viewer.css CHANGED
@@ -3,13 +3,14 @@
3
3
  * They inherit through the shadow root; the defaults below apply only when unset.
4
4
  */
5
5
  .draft-viewer {
6
- --dv-border: var(--draft-border, #cbd5e1);
7
- --dv-ink: var(--draft-ink, #1e293b);
8
- --dv-bg: var(--draft-bg, #fff);
9
- --dv-focus: var(--draft-focus, #2563eb);
10
- --dv-shadow: var(--draft-shadow, rgb(15 23 42 / 0.12));
11
- --dv-warning-ink: var(--draft-warning-ink, #9a3412);
12
- --dv-warning-bg: var(--draft-warning-bg, #fff7ed);
6
+ /* The viewer sets color-scheme from the page; each default has a dark value. */
7
+ --dv-border: var(--draft-border, light-dark(#cbd5e1, #3d4450));
8
+ --dv-ink: var(--draft-ink, light-dark(#1e293b, #e7eaef));
9
+ --dv-bg: var(--draft-bg, light-dark(#fff, #16191e));
10
+ --dv-focus: var(--draft-focus, light-dark(#2563eb, #7fa4e6));
11
+ --dv-shadow: var(--draft-shadow, light-dark(rgb(15 23 42 / 0.12), rgb(0 0 0 / 0.4)));
12
+ --dv-warning-ink: var(--draft-warning-ink, light-dark(#9a3412, #fdba74));
13
+ --dv-warning-bg: var(--draft-warning-bg, light-dark(#fff7ed, #431407));
13
14
  position: relative;
14
15
  display: grid;
15
16
  grid-template-rows: auto minmax(8rem, 1fr) auto auto;
@@ -126,7 +127,7 @@
126
127
  }
127
128
 
128
129
  /* The anchor layer: slot targets above the drawing. Slot content takes no pointer input unless
129
- it is marked data-draft-input (host.css). */
130
+ it is marked data-draft-input. */
130
131
  .draft-anchors {
131
132
  position: absolute;
132
133
  inset: 0;
@@ -150,6 +151,11 @@
150
151
  box-sizing: border-box;
151
152
  pointer-events: none;
152
153
  }
154
+ /* Marked content in a mountViewer target, in the page's DOM. The element's slotted content gets the
155
+ same rule from host.css, because these selectors do not reach into slots. */
156
+ .draft-anchor [data-draft-input] {
157
+ pointer-events: auto;
158
+ }
153
159
  .draft-anchor--body {
154
160
  overflow: clip;
155
161
  }