@draftably/editor 0.2.0 → 0.4.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 (44) hide show
  1. package/README.md +5 -3
  2. package/dist/assets/engine.worker-C6o2x40z.js +7609 -0
  3. package/dist/element.js +171 -17
  4. package/dist/index.js +9837 -8468
  5. package/dist/types/src/cli/raster-fonts.d.ts +3 -0
  6. package/dist/types/src/components/canvas/Canvas.d.ts +4 -0
  7. package/dist/types/src/components/scene/NodeView.d.ts +7 -0
  8. package/dist/types/src/components/scene/parts.d.ts +7 -11
  9. package/dist/types/src/components/session-context.d.ts +4 -1
  10. package/dist/types/src/dsl/cells.d.ts +1 -0
  11. package/dist/types/src/dsl/compile.d.ts +15 -1
  12. package/dist/types/src/dsl/corridors.d.ts +38 -0
  13. package/dist/types/src/dsl/legend-notes.d.ts +14 -0
  14. package/dist/types/src/dsl/syntax.d.ts +3 -1
  15. package/dist/types/src/editor/css.d.ts +3 -0
  16. package/dist/types/src/editor/element.d.ts +8 -6
  17. package/dist/types/src/editor/internal.d.ts +483 -0
  18. package/dist/types/src/editor/mount.d.ts +70 -5
  19. package/dist/types/src/graph-api/core.d.ts +125 -0
  20. package/dist/types/src/model/appearance.d.ts +19 -0
  21. package/dist/types/src/model/colors.d.ts +10 -2
  22. package/dist/types/src/model/labels.d.ts +22 -6
  23. package/dist/types/src/model/types.d.ts +9 -0
  24. package/dist/types/src/runtime/anchors.d.ts +46 -0
  25. package/dist/types/src/runtime/camera.d.ts +41 -0
  26. package/dist/types/src/runtime/element-base.d.ts +40 -0
  27. package/dist/types/src/runtime/geometry.d.ts +72 -0
  28. package/dist/types/src/runtime/host.d.ts +46 -0
  29. package/dist/types/src/runtime/page-shared.d.ts +24 -0
  30. package/dist/types/src/runtime/policy.d.ts +7 -0
  31. package/dist/types/src/runtime/render.d.ts +10 -0
  32. package/dist/types/src/runtime/svg-renderer.d.ts +8 -0
  33. package/dist/types/src/runtime/types.d.ts +115 -0
  34. package/dist/types/src/runtime/version.d.ts +2 -0
  35. package/dist/types/src/runtime/viewer.d.ts +123 -0
  36. package/dist/types/src/state/active-session.d.ts +7 -1
  37. package/dist/types/src/state/dom-root.d.ts +8 -0
  38. package/dist/types/src/state/session/document.d.ts +3 -1
  39. package/dist/types/src/state/session/editor.d.ts +3 -2
  40. package/dist/types/src/state/session/index.d.ts +5 -1
  41. package/package.json +1 -1
  42. package/dist/assets/engine.worker-DwN9io_m.js +0 -6856
  43. package/dist/types/src/cli/png.d.ts +0 -23
  44. package/dist/types/src/model/embed.d.ts +0 -17
@@ -0,0 +1,115 @@
1
+ import type { Geometry } from './geometry';
2
+ export type Severity = 'error' | 'warning' | 'info';
3
+ export interface SourceLocation {
4
+ sourceId?: string;
5
+ line: number;
6
+ column?: number;
7
+ }
8
+ export interface Diagnostic {
9
+ code: string;
10
+ severity: Severity;
11
+ message: string;
12
+ location?: SourceLocation;
13
+ itemIds: readonly string[];
14
+ related?: readonly {
15
+ message: string;
16
+ location: SourceLocation;
17
+ }[];
18
+ nativeCode?: string;
19
+ }
20
+ export interface CompileLimits {
21
+ maxSourceChars: number;
22
+ maxSourceBytes: number;
23
+ maxObjects: number;
24
+ maxEdges: number;
25
+ maxDepth: number;
26
+ }
27
+ export interface RenderLimits extends CompileLimits {
28
+ maxOutputBytes: number;
29
+ }
30
+ export type LinkPolicy = {
31
+ mode: 'none';
32
+ } | {
33
+ mode: 'safe';
34
+ baseUrl?: string;
35
+ target?: '_self' | '_blank';
36
+ resolve?: (request: {
37
+ itemId: string;
38
+ href: string;
39
+ }) => string | null;
40
+ cacheKey?: string;
41
+ };
42
+ export interface CommonRenderOptions {
43
+ title?: string;
44
+ description?: string;
45
+ includeSource?: boolean;
46
+ links?: LinkPolicy;
47
+ styleNonce?: string;
48
+ state?: string | null;
49
+ sourceId?: string;
50
+ signal?: AbortSignal;
51
+ limits?: Partial<RenderLimits>;
52
+ }
53
+ export type RenderOptions = CommonRenderOptions & ({
54
+ target?: 'image';
55
+ idPrefix?: never;
56
+ fonts?: 'embed';
57
+ } | {
58
+ target: 'inline';
59
+ idPrefix: string;
60
+ fonts?: 'embed' | 'host';
61
+ });
62
+ export interface ValidateOptions {
63
+ sourceId?: string;
64
+ signal?: AbortSignal;
65
+ limits?: Partial<CompileLimits>;
66
+ }
67
+ export interface ItemSummary {
68
+ id: string;
69
+ kind: 'node' | 'group' | 'edge';
70
+ label: string;
71
+ line: number;
72
+ from?: string;
73
+ to?: string;
74
+ }
75
+ export interface DiagramSummary {
76
+ title: string;
77
+ description?: string;
78
+ width: number;
79
+ height: number;
80
+ viewBox: readonly [number, number, number, number];
81
+ items: readonly ItemSummary[];
82
+ states: readonly {
83
+ id: string;
84
+ label: string;
85
+ }[];
86
+ activeState: string | null;
87
+ }
88
+ export interface RenderedDiagram extends DiagramSummary {
89
+ svg: string;
90
+ /**
91
+ * Where each node, group and edge is drawn, in the SVG's own units (its `viewBox`), in the graph
92
+ * API's shapes. `null` for `compare` and `states` drawings, which repeat items across panels.
93
+ */
94
+ geometry: Geometry | null;
95
+ provenance: {
96
+ runtimeVersion: string;
97
+ dslVersion: 1;
98
+ fontMetricsVersion: string;
99
+ renderContextVersion: string;
100
+ };
101
+ }
102
+ export type RenderFailure = {
103
+ ok: false;
104
+ reason: 'input' | 'limit' | 'aborted' | 'environment' | 'internal';
105
+ diagnostics: readonly Diagnostic[];
106
+ };
107
+ export type RenderResult = {
108
+ ok: true;
109
+ value: RenderedDiagram;
110
+ diagnostics: readonly Diagnostic[];
111
+ } | RenderFailure;
112
+ export type ValidationResult = {
113
+ ok: true;
114
+ diagnostics: readonly Diagnostic[];
115
+ } | RenderFailure;
@@ -0,0 +1,2 @@
1
+ export declare const runtimeVersion: string;
2
+ export { fontMetricsVersion } from '../model/font-faces';
@@ -0,0 +1,123 @@
1
+ import { type Camera, type CameraReason, type FrameOptions, type MoveResult } from './camera';
2
+ import { type Anchor, type DraftSlot } from './anchors';
3
+ import { type Geometry } from './geometry';
4
+ import { fontMetricsVersion, runtimeVersion } from './version';
5
+ import type { CommonRenderOptions, Diagnostic, LinkPolicy, RenderFailure, RenderResult } from './types';
6
+ export { fontMetricsVersion, runtimeVersion };
7
+ export type { Camera, CameraReason, FrameOptions, MoveResult } from './camera';
8
+ export type { Box, EdgeOut, Geometry, PlacedBox } from './geometry';
9
+ export type { Anchor, DraftSlot } from './anchors';
10
+ export { ZOOM_MAX, ZOOM_MIN } from './camera';
11
+ export type ViewerExecution = {
12
+ mode: 'worker';
13
+ createWorker?: () => Worker;
14
+ timeoutMs?: number;
15
+ } | {
16
+ mode: 'main';
17
+ };
18
+ export type ViewerRenderOptions = Omit<CommonRenderOptions, 'signal' | 'state'> & {
19
+ fonts?: 'host' | 'embed';
20
+ };
21
+ export interface ViewerOptions {
22
+ label?: string;
23
+ toolbar?: boolean;
24
+ /**
25
+ * The keyboard and screen-reader list of items. `'hidden'` (default) keeps it for assistive tech
26
+ * and shows it while it holds focus; `'visible'` always shows it under the drawing.
27
+ */
28
+ outline?: 'visible' | 'hidden';
29
+ execution?: ViewerExecution;
30
+ /** `auto` (default) hides slot bodies and shows titles again below a zoom of 0.4. */
31
+ detail?: 'auto' | 'full';
32
+ render?: ViewerRenderOptions;
33
+ }
34
+ export interface UpdateOptions {
35
+ camera?: 'preserve' | 'fit';
36
+ state?: string | null;
37
+ signal?: AbortSignal;
38
+ }
39
+ export type UpdateResult = {
40
+ status: 'committed';
41
+ revision: number;
42
+ value: Extract<RenderResult, {
43
+ ok: true;
44
+ }>['value'];
45
+ diagnostics: readonly Diagnostic[];
46
+ } | {
47
+ status: 'error';
48
+ revision: number;
49
+ error: RenderFailure;
50
+ } | {
51
+ status: 'superseded' | 'destroyed' | 'aborted';
52
+ revision: number;
53
+ };
54
+ export interface ViewerEvents {
55
+ /** After each commit, after `anchor()`, and with `[]` before `destroy` detaches the targets. */
56
+ anchors: {
57
+ anchors: readonly Anchor[];
58
+ };
59
+ /** After each commit: the drawing, and where each item is (`null` for compare and states). */
60
+ render: {
61
+ revision: number;
62
+ value: Extract<RenderResult, {
63
+ ok: true;
64
+ }>['value'];
65
+ geometry: Geometry | null;
66
+ };
67
+ diagnostics: {
68
+ revision: number;
69
+ diagnostics: readonly Diagnostic[];
70
+ stale: boolean;
71
+ };
72
+ /** At most once per animation frame, with the latest reason. */
73
+ camera: {
74
+ camera: Camera;
75
+ reason: CameraReason;
76
+ };
77
+ itemactivate: {
78
+ id: string;
79
+ kind: 'node' | 'group' | 'edge';
80
+ input: 'pointer' | 'keyboard';
81
+ revision: number;
82
+ };
83
+ /** `preventDefault()` stops the viewer opening the link. */
84
+ link: {
85
+ itemId: string;
86
+ href: string;
87
+ target: '_self' | '_blank';
88
+ preventDefault(): void;
89
+ };
90
+ /** A right-click or the menu key; `id` is null on the background. `preventDefault()` stops the browser's menu. */
91
+ contextmenu: {
92
+ id: string | null;
93
+ kind?: ItemKind;
94
+ clientX: number;
95
+ clientY: number;
96
+ preventDefault(): void;
97
+ };
98
+ }
99
+ export type ItemKind = 'node' | 'group' | 'edge';
100
+ export interface ViewerHandle {
101
+ /** Resolves after the first commit or failure; then after each later one. */
102
+ readonly ready: Promise<UpdateResult>;
103
+ update(source: string, options?: UpdateOptions): Promise<UpdateResult>;
104
+ /** Where each item is drawn, in world units. `null` before the first commit, and for compare and states. The same object for one revision. */
105
+ geometry(): Geometry | null;
106
+ on<K extends keyof ViewerEvents>(type: K, listener: (event: ViewerEvents[K]) => void): () => void;
107
+ getCamera(): Camera;
108
+ /** Zoom is clamped to `ZOOM_MIN`–`ZOOM_MAX`. */
109
+ setCamera(camera: Camera): void;
110
+ /** Frame these items, or the whole drawing without ids. At most actual size by default. */
111
+ fit(ids?: readonly string[], options?: FrameOptions): MoveResult;
112
+ /** The least move that shows the item; zooms out only if it does not fit. */
113
+ reveal(id: string, options?: FrameOptions): MoveResult;
114
+ focusItem(id: string): boolean;
115
+ /**
116
+ * Plain-DOM hosts only: keep a target for each slot (`body:<id>`, `overlay:<id>`). Targets come
117
+ * in the `anchors` event; put content in them. The elements set this from their marked children.
118
+ */
119
+ anchor(slots: readonly DraftSlot[]): void;
120
+ destroy(): void;
121
+ }
122
+ export declare function mountViewer(host: HTMLElement, options?: ViewerOptions): ViewerHandle;
123
+ export type { LinkPolicy };
@@ -1,5 +1,6 @@
1
1
  import type { DiagramSession } from './session';
2
2
  export declare function activeSession(): DiagramSession;
3
+ export declare const hasActiveSession: () => boolean;
3
4
  export declare const setActiveSession: (session: DiagramSession) => {
4
5
  dispose: () => void;
5
6
  } & {
@@ -46,7 +47,8 @@ export declare const setActiveSession: (session: DiagramSession) => {
46
47
  redo: () => void;
47
48
  canUndo: () => boolean;
48
49
  canRedo: () => boolean;
49
- setCamera: (camera: import("../model/types").Camera) => void;
50
+ setCamera: (camera: import("../model/types").Camera, reason?: import("../runtime/camera").CameraReason) => void;
51
+ onCamera: (listener: (reason: import("../runtime/camera").CameraReason) => void) => () => boolean;
50
52
  disableBrowserStorage: () => boolean;
51
53
  setPersistenceBlocked: (blocked: boolean) => void;
52
54
  persist: () => void;
@@ -476,4 +478,8 @@ export declare const setActiveSession: (session: DiagramSession) => {
476
478
  onDoubleClick: (e: MouseEvent) => void;
477
479
  selectForContextMenu: (e: MouseEvent) => void;
478
480
  dragKind: () => string | undefined;
481
+ } & {
482
+ describeLink: (href: string) => string;
479
483
  };
484
+ /** A destroyed session stops being the target of shortcuts and commands. */
485
+ export declare const releaseActiveSession: (session: DiagramSession) => void;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Lookups that work when the editor renders inside a shadow root. A page-level listener sees an
3
+ * event retargeted to the shadow host, and `document` lookups cannot see inside a shadow root.
4
+ */
5
+ /** The document or shadow root that holds `node`. */
6
+ export declare const rootOf: (node: Node) => Document | ShadowRoot;
7
+ /** The element the event started on, inside any shadow root. */
8
+ export declare const eventTarget: (e: Event) => EventTarget | null;
@@ -1,4 +1,5 @@
1
1
  import type { Camera, Diagram } from '../../model/types';
2
+ import type { CameraReason } from '../../runtime/camera';
2
3
  import type { CanvasTextPart } from './canvas-text';
3
4
  import type { SessionOptions } from '.';
4
5
  export interface HistoryEntry {
@@ -69,7 +70,8 @@ export declare function createDocument(s: CanvasTextPart, options: SessionOption
69
70
  redo: () => void;
70
71
  canUndo: () => boolean;
71
72
  canRedo: () => boolean;
72
- setCamera: (camera: Camera) => void;
73
+ setCamera: (camera: Camera, reason?: CameraReason) => void;
74
+ onCamera: (listener: (reason: CameraReason) => void) => () => boolean;
73
75
  disableBrowserStorage: () => boolean;
74
76
  setPersistenceBlocked: (blocked: boolean) => void;
75
77
  persist: () => void;
@@ -25,8 +25,9 @@ export interface DragFeedback {
25
25
  near?: string;
26
26
  };
27
27
  }
28
- export declare const MIN_ZOOM = 0.08;
29
- export declare const MAX_ZOOM = 4;
28
+ /** The zoom range both handles share: `ZOOM_MIN`–`ZOOM_MAX` in `runtime/camera.ts`. */
29
+ export declare const MIN_ZOOM = 0.02;
30
+ export declare const MAX_ZOOM = 8;
30
31
  export { NodeGeometry };
31
32
  export declare function createEditor(s: DocumentPart & ScenePart): {
32
33
  tool: import("solid-js").Accessor<Tool>;
@@ -62,7 +62,8 @@ export declare function createDiagramSession(options?: SessionOptions): {
62
62
  redo: () => void;
63
63
  canUndo: () => boolean;
64
64
  canRedo: () => boolean;
65
- setCamera: (camera: import("../../model/types").Camera) => void;
65
+ setCamera: (camera: import("../../model/types").Camera, reason?: import("../../runtime/camera").CameraReason) => void;
66
+ onCamera: (listener: (reason: import("../../runtime/camera").CameraReason) => void) => () => boolean;
66
67
  disableBrowserStorage: () => boolean;
67
68
  setPersistenceBlocked: (blocked: boolean) => void;
68
69
  persist: () => void;
@@ -492,5 +493,8 @@ export declare function createDiagramSession(options?: SessionOptions): {
492
493
  onDoubleClick: (e: MouseEvent) => void;
493
494
  selectForContextMenu: (e: MouseEvent) => void;
494
495
  dragKind: () => string | undefined;
496
+ } & {
497
+ /** What opening `href` does, for a link mark's label. */
498
+ describeLink: (href: string) => string;
495
499
  };
496
500
  export type DiagramSession = ReturnType<typeof createDiagramSession>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@draftably/editor",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "The Draftably diagram editor: drag boxes and lines, and get the .draft source back.",
5
5
  "license": "MIT",
6
6
  "type": "module",