@rasamjs/connectors 0.1.0 → 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.
package/API.md CHANGED
@@ -12,13 +12,17 @@ is created; supply your own if needed.
12
12
 
13
13
  `create(options)` returns an ordinary `Path` in one labelled core change group:
14
14
 
15
- - `start`, `end`: `{ target, anchor? }` or `{ point: { x, y } }`. Free points use drawing
16
- units. Targets are transformable shapes/groups/viewports in the same drawing,
15
+ - `start`, `end`: `{ target, anchor? }`, `{ target, port }` or `{ point: { x, y } }`.
16
+ Free points use drawing units. Targets are transformable shapes/groups/viewports in the same drawing,
17
17
  excluding the root, connectors and groups containing connectors.
18
18
  - `anchor`: `auto` (default), `top`, `right`, `bottom`, `left`, or `{ x, y }` normalized
19
19
  between 0 and 1 within the target's local geometric bounds. `{ x: 1, y: 0.5 }` is
20
20
  right-center and follows resizing. Sides rotate with the target. Auto intersects the
21
21
  ray toward the other endpoint with the local bounds rectangle.
22
+ - `port`: the name of one of the target's ports, read structurally from its
23
+ `portDefinitions` (core's `PortDefinition`), such as a component's `ports()`. The end
24
+ sits exactly on the port and leaves along the port's side, transformed with the
25
+ target; a port without a side has no lead. An unknown port rejects the edit.
22
26
  - `routing`: `straight` (default) or `elbow`. Elbows use orthogonal drawing-space
23
27
  segments with 16-unit outward leads. They do not avoid obstacles; close/opposing
24
28
  anchors can produce backtracking. Curved routing and connector labels are deferred.
@@ -27,8 +31,9 @@ is created; supply your own if needed.
27
31
  - `stroke`: nonempty SVG paint, default `#334155`; `strokeWidth`: finite nonnegative
28
32
  number, default 2. Edit subsequent appearance through ordinary path APIs.
29
33
 
30
- `nodes` is a frozen snapshot of current paths in document order. `read(path)` returns
31
- `{ path, start, end, routing }`. `update(path, { start?, end?, routing? })` changes a
34
+ `nodes` is a frozen snapshot of current paths in document order. `links(target, port?)`
35
+ lists the connectors with an end on `target`, or only on its port named `port`, in
36
+ the same order. `read(path)` returns `{ path, start, end, routing }`. `update(path, { start?, end?, routing? })` changes a
32
37
  connection in one labelled edit. `remove(path)` detaches it reversibly in one edit;
33
38
  its marker resources remain available. Undoing creation also removes newly created
34
39
  endpoint IDs and markers. Undo/redo retain path and endpoint identities.
@@ -39,10 +44,21 @@ operation/group, including ordinary setters, transformer gestures and transactio
39
44
  Getter-only operations do not route. Replay and rollback restore saved path data
40
45
  without recomputing it. Camera changes with source `viewport` do not route.
41
46
 
47
+ Only the connectors a change reaches are routed: those inside a changed subtree and
48
+ those attached to a changed node, its descendants or its ancestors. Attachments are
49
+ found through core's typed-reference index (`context.defs.consumersOf(target)`), so a
50
+ move costs about the same with 10 or 1,000 connectors in the drawing. `links()` uses the
51
+ same index. `bun run bench` measures 500 parts with 10 and 1,000 links
52
+ (`reports/benchmark.json`; `--revision=<commit>` measures older connector sources).
53
+
42
54
  Geometry uses fill bounds, excluding strokes and clipping. Curved/irregular targets
43
55
  use their bounds rectangle for automatic anchors. Empty/unavailable geometry or an
44
- unmappable automatic anchor/path rejects creation/update. Existing paths retain their last geometry
45
- while targets are detached or unmappable; undo and later changes restore tracking.
56
+ unmappable automatic anchor/path rejects creation/update. When a target leaves the
57
+ drawing (removal, Delete, Cut, or removing a parent) or its port disappears (for
58
+ example after a prop change), that end becomes a loose point where the path ends now,
59
+ in the same operation and undo step, and the target is no longer referenced. Undo
60
+ restores the attachment. Existing paths retain their last geometry while targets are
61
+ unmappable.
46
62
  A connector cannot be placed inside its own endpoint target, which would make routing
47
63
  cyclic. Failed connector commands cancel partial edits. Caller setters follow core's
48
64
  failure semantics; use a history transaction for rollback when dependent writes fail.
@@ -54,17 +70,23 @@ Drawing disposal destroys the service and its tools. Recreate for a replacement
54
70
 
55
71
  ## Persistence
56
72
 
57
- Versioned routing, anchors and free points live in `data-rasam-connector`. Attached
73
+ Versioned routing, anchors, ports and free points live in `data-rasam-connector`
74
+ (version 1). A port end is saved as `{ "port": "b" }`; readers without port support
75
+ treat it as an automatic anchor on the same target. Attached
58
76
  targets use typed href fragments in the reserved `data-rasam-connector-start` and
59
77
  `data-rasam-connector-end` attributes. Core recognizes them during clone, export/import
60
78
  and ID remapping. Markers use normal typed URL references. No custom catalog is needed.
61
79
 
62
80
  Cloning a whole group rebinds copied connectors to copied endpoints. Cloning a path
63
- alone shares its external endpoints/markers by default. Exporting a connector alone
64
- includes referenced shapes as dependencies in defs; a whole drawing retains visible
65
- shapes and attachments. Permanently destroying a referenced target requires unbinding
66
- its consumers first; editor deletion uses reversible removal. Use the matching current
67
- core build while these APIs remain unreleased.
81
+ alone shares its external endpoints/markers by default. Targets are links, not
82
+ resources: exporting, copying or duplicating a connector never copies the shapes it
83
+ joins into defs. Importing or pasting one whose target was left out turns that end into
84
+ a loose point where it was, and ends whose targets were copied along rebind to the
85
+ copies. A whole drawing retains visible shapes and attachments. Permanently destroying
86
+ a target that a connector still references is refused, as for any referenced node;
87
+ editor deletion uses reversible removal, which loosens those ends first. Connectors
88
+ 0.2.0 requires core 0.3.0 or a compatible newer 0.3.x release. Earlier connector
89
+ versions do not provide the named-port or partial-copy behavior above.
68
90
 
69
91
  ## Geometry helpers
70
92
 
@@ -85,8 +107,13 @@ same routing/arrows/stroke/strokeWidth settings, plus:
85
107
  - `onError(error)`: receives pointer/callback errors; otherwise errors propagate.
86
108
  - `onExit()`: runs after Escape exits an idle enabled tool.
87
109
 
88
- Hover shows four side hints, five overlay pixels in radius at every zoom. Press within
89
- twelve client pixels of a side to choose it; body presses use auto anchors. Empty-space
110
+ Hover shows four side hints, five overlay pixels in radius at every zoom. A target with
111
+ ports, such as a component, shows its ports instead (`data-connector-port`). Press or
112
+ release within twelve client pixels of a hint to choose it, a side anchor or a
113
+ `{ target, port }` end; the chosen hint is filled (`data-connector-active`). Other
114
+ body presses use auto anchors. Hit testing never reports groups, so a hit that
115
+ `selectable` rejects, such as a component's rendered child, resolves to its nearest
116
+ accepted ancestor. Empty-space
90
117
  presses/releases use free points. Previews never edit the document. Release creates one
91
118
  labelled edit; coincident endpoints create nothing. The tool stays enabled so the app
92
119
  can choose keep-tool behavior.
@@ -100,13 +127,15 @@ switching other application modes.
100
127
 
101
128
  ## Editor integration entry
102
129
 
103
- `@rasamjs/connectors/editor` exports `connectorEditing()`, a structural extension
130
+ `@rasamjs/connectors/editor` exports `connectorEditing(options?)`, a structural extension
104
131
  factory. Its value is the current `Connectors` service. It registers
105
- `connector-straight` (C) and `connector-elbow` (Shift+C), with matching command IDs,
106
- active-tool metadata, current selection/layer restrictions, paint, keep-tool and
107
- camera/capture cleanup. Escape cancels a drag first and exits an idle tool;
108
- document replacement, editing/dialog actions, tool changes and disposal interrupt
109
- sessions. Read-only camera commands retain an idle connector mode.
132
+ `connector-straight` (C) and `connector-elbow` (Shift+C), or the `tools` you pass:
133
+ `ConnectorEditingTool` entries `{ id, label, key, routing?, arrows?, hint? }`, for
134
+ example `{ id: 'wire', label: 'Wire', key: 'W', routing: 'elbow', arrows: 'none' }`.
135
+ Each tool has a matching command ID and active-tool metadata, current selection/layer
136
+ restrictions, paint, keep-tool and camera/capture cleanup. Escape cancels a drag first
137
+ and exits an idle tool; document replacement, editing/dialog actions, tool changes and
138
+ disposal interrupt sessions. Read-only camera commands retain an idle connector mode.
110
139
 
111
140
  `ConnectorTool.paint` reads an immutable `{ stroke, strokeWidth }` snapshot and
112
141
  accepts a validated replacement. Updates repaint an active preview and apply to
package/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.2.0 — 2026-11-07
6
+
7
+ - Ignore disposed derived children when finding affected links during component
8
+ hydration, so copying and pasting rendered components keeps its undo step.
9
+ - Attach ends to named ports with `{ target, port }`, read structurally from
10
+ `portDefinitions` such as a component's `ports()`. Port ends sit exactly on the port,
11
+ lead out along its side and save as `{ "port": "b" }` in version 1 metadata.
12
+ - When a target leaves the drawing or its port disappears, that end becomes a loose
13
+ point where it was, in the same undo step; undo reattaches it. Deleted targets are no
14
+ longer saved as hidden dependencies in `<defs>`.
15
+ - Copying or pasting a connector without its targets pastes loose ends instead of
16
+ hidden copies of the targets.
17
+ - Add `links(target, port?)`.
18
+ - Route only the connectors a change reaches, found through core's reference index:
19
+ with 500 parts, moving one part 100 times takes 20 ms with 1,000 links (1,726 ms
20
+ before) and 15 ms with 10 links. Creating 1,000 links takes 1.1 s instead of 11.2 s.
21
+ Add `bun run bench`.
22
+ - The tool shows a target's ports instead of its side hints, snaps to the nearest one
23
+ within twelve client pixels, fills the chosen hint, and resolves a rejected hit (such
24
+ as a component's rendered child) to its nearest accepted ancestor.
25
+ - `connectorEditing({ tools })` registers custom tools, such as a Wire tool with elbow
26
+ routing and no arrows, in place of Connector and Elbow connector.
27
+ - TypeScript: `ConnectorEndpoint` has a third, port variant. Narrow with
28
+ `'anchor' in endpoint` before reading `anchor`.
29
+
30
+ ## 0.1.0 — 2026-11-06
31
+
5
32
  - Add `./editor` connector integration with registered tool metadata, live paint,
6
33
  keep-tool and scoped camera/input cleanup. Add `ConnectorTool.paint` for preview updates.
7
34
 
package/README.md CHANGED
@@ -4,7 +4,12 @@ The optional [editor adapter](API.md#editor-integration-entry) packages connecto
4
4
  services and registered straight/elbow tools, including live paint and input cleanup.
5
5
 
6
6
  Attached straight and elbow lines and marker arrows for rasam SVG drawings. Core is
7
- the only runtime peer. This package is unreleased and remains private.
7
+ the only runtime peer. Version 0.2.0 requires `@rasamjs/core@^0.3.0` for named ports,
8
+ loose-end persistence and indexed routing. Source manifests stay private between releases.
9
+
10
+ ```sh
11
+ npm install @rasamjs/core@^0.3.0 @rasamjs/connectors@^0.2.0
12
+ ```
8
13
 
9
14
  ```ts
10
15
  import { SVG } from '@rasamjs/core';
@@ -24,6 +29,10 @@ const tool = new ConnectorTool(connectors, { routing: 'straight' });
24
29
  tool.enabled = true;
25
30
  ```
26
31
 
32
+ Ends can also attach to a component's named ports, `{ target: chip, port: 'p3' }`, and
33
+ `connectors.links(chip)` lists the connectors on it. Deleting a target keeps its
34
+ connectors, with a loose end where it was.
35
+
27
36
  Moving or resizing an endpoint, or its parent, updates the connector inside the same
28
37
  model operation and change group. History records one undo step for a move and all
29
38
  its attached lines. Replay restores stored geometry without routing again.
@@ -42,4 +51,5 @@ bun run --cwd packages/connectors test
42
51
  bun run --cwd packages/connectors test:browser
43
52
  bun run --cwd packages/connectors typecheck
44
53
  bun run --cwd packages/connectors build
54
+ bun run --cwd packages/connectors bench
45
55
  ```
package/RELEASING.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # Releasing connectors
2
2
 
3
- The package remains private and unreleased. Phase 10 does not authorize publishing,
4
- pushing or changing an existing approved size cap.
3
+ The source manifest stays private between releases. Version 0.2.0 is paired with
4
+ core 0.3.0 and adds named ports, loose ends, partial-copy remapping and indexed routing.
5
+ The owner authorized release preparation, publication and pushing on 2026-11-07.
6
+ Existing approved size caps stay unchanged.
5
7
 
6
8
  Run scoped format, typecheck, unit, build, API, docs, browser, consumer and size checks.
7
9
  Run `api:update` only after reviewing the API diff. The root's 5 KiB gzip and optional
@@ -1,6 +1,6 @@
1
1
  import { Path } from '@rasamjs/core';
2
2
  import type { Svg } from '@rasamjs/core';
3
- import type { ConnectorOptions, ConnectorState } from './types.js';
3
+ import type { ConnectorOptions, ConnectorState, ConnectorTarget } from './types.js';
4
4
  export declare class Connectors {
5
5
  readonly drawing: Svg;
6
6
  private disposed;
@@ -11,6 +11,8 @@ export declare class Connectors {
11
11
  onDispose(listener: () => void): () => void;
12
12
  get nodes(): readonly Path[];
13
13
  read(path: Path): ConnectorState;
14
+ /** Connectors with an end on `target`, or only on its port named `port`. */
15
+ links(target: ConnectorTarget, port?: string): readonly Path[];
14
16
  create(options: ConnectorOptions): Path;
15
17
  update(path: Path, patch: Partial<Pick<ConnectorOptions, 'start' | 'end' | 'routing'>>): void;
16
18
  remove(path: Path): void;
@@ -19,7 +21,17 @@ export declare class Connectors {
19
21
  private assertPath;
20
22
  private validate;
21
23
  private validateEndpoint;
22
- private affects;
24
+ /** An end whose target left the drawing, or whose port is gone, stays where it is. */
25
+ private loosen;
26
+ /** Connectors in this drawing with an end on `target`, from core's reference index. */
27
+ private attached;
28
+ /**
29
+ * Connectors to route after a change: those inside a changed subtree, and those attached
30
+ * to a changed node, its descendants or its ancestors, since parents move, resize or
31
+ * reparent targets and a descendant changes a group's bounds. The work follows the
32
+ * size of the change, not the number of connectors.
33
+ */
34
+ private affected;
23
35
  private route;
24
36
  private edit;
25
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"connectors.d.ts","sourceRoot":"","sources":["../src/connectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,EAAE,GAAG,EAAW,MAAM,eAAe,CAAC;AAYlD,OAAO,KAAK,EAAqB,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAkBtF,qBAAa,UAAU;IAIT,QAAQ,CAAC,OAAO,EAAE,GAAG;IAHjC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,YAAqB,OAAO,EAAE,GAAG,EAuBhC;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAO1C;IACD,IAAI,KAAK,IAAI,SAAS,IAAI,EAAE,CAG3B;IACD,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,cAAc,CAG/B;IACD,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAgCtC;IACD,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC,CAAC,GAAG,IAAI,CAS5F;IACD,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAGvB;IACD,OAAO,IAAI,IAAI,CAcd;IACD,OAAO,CAAC,UAAU;IAGlB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,QAAQ;IAmBhB,OAAO,CAAC,gBAAgB;IAwBxB,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,KAAK;IAuBb,OAAO,CAAC,IAAI;CAgBb"}
1
+ {"version":3,"file":"connectors.d.ts","sourceRoot":"","sources":["../src/connectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,EAAE,GAAG,EAAW,MAAM,eAAe,CAAC;AAoBlD,OAAO,KAAK,EAEV,gBAAgB,EAChB,cAAc,EACd,eAAe,EAChB,MAAM,YAAY,CAAC;AAkBpB,qBAAa,UAAU;IAIT,QAAQ,CAAC,OAAO,EAAE,GAAG;IAHjC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,YAAqB,OAAO,EAAE,GAAG,EAyBhC;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAO1C;IACD,IAAI,KAAK,IAAI,SAAS,IAAI,EAAE,CAG3B;IACD,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,cAAc,CAG/B;IACD,4EAA4E;IAC5E,KAAK,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,IAAI,EAAE,CAiB7D;IACD,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAgCtC;IACD,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC,CAAC,GAAG,IAAI,CAS5F;IACD,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAGvB;IACD,OAAO,IAAI,IAAI,CAcd;IACD,OAAO,CAAC,UAAU;IAGlB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,QAAQ;IAmBhB,OAAO,CAAC,gBAAgB;IA2BxB,sFAAsF;IACtF,OAAO,CAAC,MAAM;IAgBd,uFAAuF;IACvF,OAAO,CAAC,QAAQ;IAYhB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,KAAK;IAuBb,OAAO,CAAC,IAAI;CAgBb"}
@@ -1,8 +1,8 @@
1
1
  import { Path } from '@rasamjs/core';
2
2
  import { Guards } from '@rasamjs/core/advanced';
3
3
  import { beginChangeGroup, deriveChanges } from '@rasamjs/core/changes';
4
- import { isConnector, readConnector, writeConnector } from './metadata.js';
5
- import { connectorPort, endpointCenter, pathData, routeConnector, validateAnchor, validatePoint, } from './routing.js';
4
+ import { endpointAttribute, isConnector, pathEnd, readConnector, unbound, writeConnector, } from './metadata.js';
5
+ import { connectorPort, endpointCenter, findPort, pathData, routeConnector, validateAnchor, validatePoint, } from './routing.js';
6
6
  const owners = new WeakMap();
7
7
  const drawableTags = new Set([
8
8
  'rect',
@@ -39,10 +39,12 @@ export class Connectors {
39
39
  this.cleanups.push(deriveChanges(drawing, (event) => {
40
40
  if (event.source === 'viewport')
41
41
  return;
42
- for (const path of this.nodes) {
43
- const state = readConnector(path);
44
- if (event.nodes.some((changed) => changed === path || this.affects(changed, state)))
45
- this.route(state);
42
+ for (const path of this.affected(event.nodes)) {
43
+ let state = readConnector(path);
44
+ const loose = this.loosen(state);
45
+ if (loose !== state || unbound.has(state.start) || unbound.has(state.end))
46
+ writeConnector(path, (state = loose));
47
+ this.route(state);
46
48
  }
47
49
  }), drawing.onDispose(() => this.destroy()));
48
50
  }
@@ -66,6 +68,20 @@ export class Connectors {
66
68
  this.assertPath(path);
67
69
  return readConnector(path);
68
70
  }
71
+ /** Connectors with an end on `target`, or only on its port named `port`. */
72
+ links(target, port) {
73
+ this.assertLive();
74
+ if (port !== undefined && (typeof port !== 'string' || !port))
75
+ throw new TypeError('Port names must be non-empty strings');
76
+ return Object.freeze(this.attached(target)
77
+ .filter((path) => {
78
+ const { start, end } = readConnector(path);
79
+ return [start, end].some((endpoint) => 'target' in endpoint &&
80
+ endpoint.target === target &&
81
+ (port === undefined || ('port' in endpoint && endpoint.port === port)));
82
+ })
83
+ .sort((a, b) => (a.el.compareDocumentPosition(b.el) & 4 ? -1 : 1)));
84
+ }
69
85
  create(options) {
70
86
  this.assertLive();
71
87
  this.validate(options);
@@ -141,7 +157,7 @@ export class Connectors {
141
157
  if (!isConnector(path) ||
142
158
  path.isDestroyed ||
143
159
  path.context !== this.drawing.context ||
144
- !this.drawing.descendants().includes(path))
160
+ !this.drawing.el.contains(path.el))
145
161
  throw new TypeError('Expected a connector in this drawing');
146
162
  }
147
163
  validate(options) {
@@ -172,30 +188,74 @@ export class Connectors {
172
188
  target.isDestroyed ||
173
189
  target === this.drawing ||
174
190
  target.context !== this.drawing.context ||
175
- !this.drawing.descendants().includes(target) ||
191
+ !this.drawing.el.contains(target.el) ||
176
192
  target.descendants().some(isConnector))
177
193
  throw new TypeError('Endpoint target must be a drawable shape without connectors in this drawing');
178
194
  for (let node = target; node && node !== this.drawing; node = node.parent)
179
195
  if (!drawableTags.has(node.el.localName))
180
196
  throw new TypeError('Connector targets cannot be inside definitions');
181
- validateAnchor(endpoint.anchor ?? 'auto');
197
+ if (!('port' in endpoint))
198
+ return validateAnchor(endpoint.anchor ?? 'auto');
199
+ if ('anchor' in endpoint)
200
+ throw new TypeError('Endpoint needs either a port or an anchor');
201
+ if (typeof endpoint.port !== 'string' || !findPort(target, endpoint.port))
202
+ throw new TypeError(`Unknown connector port: ${String(endpoint.port)}`);
203
+ }
204
+ /** An end whose target left the drawing, or whose port is gone, stays where it is. */
205
+ loosen(state) {
206
+ const loose = (end) => {
207
+ const endpoint = state[end];
208
+ if ('point' in endpoint)
209
+ return endpoint;
210
+ const { target } = endpoint;
211
+ const gone = target.isDestroyed ||
212
+ !this.drawing.el.contains(target.el) ||
213
+ ('port' in endpoint && !findPort(target, endpoint.port));
214
+ const point = gone && pathEnd(state.path, end);
215
+ return point ? { point } : endpoint;
216
+ };
217
+ const start = loose('start'), end = loose('end');
218
+ return start === state.start && end === state.end ? state : { ...state, start, end };
182
219
  }
183
- affects(changed, { path, start, end }) {
184
- // Parents can move, resize, reparent or change a group's local bounds through a descendant.
185
- return [
186
- path,
187
- ...[start, end].flatMap((endpoint) => ('target' in endpoint ? [endpoint.target] : [])),
188
- ].some((node) => node === changed ||
189
- node.descendants().includes(changed) ||
190
- changed.descendants().includes(node));
220
+ /** Connectors in this drawing with an end on `target`, from core's reference index. */
221
+ attached(target) {
222
+ return this.drawing.context.defs
223
+ .consumersOf(target)
224
+ .filter((node) => isConnector(node) &&
225
+ this.drawing.el.contains(node.el) &&
226
+ ['start', 'end'].some((end) => node.references.get(endpointAttribute(end)) === target));
227
+ }
228
+ /**
229
+ * Connectors to route after a change: those inside a changed subtree, and those attached
230
+ * to a changed node, its descendants or its ancestors, since parents move, resize or
231
+ * reparent targets and a descendant changes a group's bounds. The work follows the
232
+ * size of the change, not the number of connectors.
233
+ */
234
+ affected(changed) {
235
+ const paths = new Set(), seen = new Set();
236
+ const visit = (node) => {
237
+ if (node.isDestroyed || seen.has(node))
238
+ return;
239
+ seen.add(node);
240
+ if (isConnector(node) && this.drawing.el.contains(node.el))
241
+ paths.add(node);
242
+ for (const path of this.attached(node))
243
+ paths.add(path);
244
+ };
245
+ for (const node of changed) {
246
+ node.descendants().forEach(visit);
247
+ for (let parent = node.parent; parent; parent = parent.parent)
248
+ visit(parent);
249
+ }
250
+ return paths;
191
251
  }
192
252
  route(state) {
193
253
  const { path, start, end } = state;
194
254
  for (const endpoint of [start, end])
195
255
  if ('target' in endpoint) {
196
- if (endpoint.target.isDestroyed || !this.drawing.descendants().includes(endpoint.target))
256
+ if (endpoint.target.isDestroyed || !this.drawing.el.contains(endpoint.target.el))
197
257
  return false;
198
- if (endpoint.target.descendants().includes(path))
258
+ if (endpoint.target.el.contains(path.el))
199
259
  throw new TypeError('A connector cannot be inside its endpoint target');
200
260
  }
201
261
  const a = endpointCenter(start), b = endpointCenter(end);
@@ -1 +1 @@
1
- {"version":3,"file":"connectors.js","sourceRoot":"","sources":["../src/connectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EACL,aAAa,EACb,cAAc,EACd,QAAQ,EACR,cAAc,EACd,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,MAAM,MAAM,GAAG,IAAI,OAAO,EAAmB,CAAC;AAC9C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,MAAM;IACN,QAAQ;IACR,SAAS;IACT,MAAM;IACN,UAAU;IACV,SAAS;IACT,MAAM;IACN,MAAM;IACN,OAAO;IACP,eAAe;IACf,KAAK;IACL,GAAG;IACH,KAAK;CACN,CAAC,CAAC;AACH,MAAM,OAAO,UAAU;IAIA,OAAO;IAHpB,QAAQ,GAAG,KAAK,CAAC;IACR,QAAQ,GAAmB,EAAE,CAAC;IAC9B,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;IACnD,YAAqB,OAAY;uBAAZ,OAAO;QAC1B,IACE,CAAC,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC;YAChC,OAAO,CAAC,WAAW;YACnB,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,IAAI;YAChC,OAAO,CAAC,EAAE,CAAC,SAAS,KAAK,KAAK;YAE9B,MAAM,IAAI,SAAS,CAAC,0CAA0C,CAAC,CAAC;QAClE,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC3F,0FAA0F;QAC1F,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,aAAa,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU;gBAAE,OAAO;YACxC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;gBAClC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBACjF,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,EACF,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CACxC,CAAC;IACJ,CAAC;IACD,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IACD,SAAS,CAAC,QAAoB;QAC5B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,OAAO,QAAQ,KAAK,UAAU;YAAE,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;QAChG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,KAAK;QACP,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,IAAU;QACb,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,CAAC,OAAyB;QAC9B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE;YACxC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;gBAC7B,CAAC,EAAE,EAAE;gBACL,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,SAAS;gBACnC,cAAc,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC;aACzC,CAAC,CAAC;YACH,cAAc,CAAC,IAAI,EAAE;gBACnB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,UAAU;aACvC,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,MAAM,EAAE,CAAC;gBACzC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;oBACvC,OAAO,EAAE,WAAW;oBACpB,WAAW,EAAE,CAAC;oBACd,YAAY,EAAE,CAAC;oBACf,IAAI,EAAE,CAAC;oBACP,IAAI,EAAE,CAAC;oBACP,MAAM,EAAE,oBAAoB;iBAC7B,CAAC,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,oBAAoB,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;gBACjF,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;oBAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC9D,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAClC,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;YAChF,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,CAAC,IAAU,EAAE,KAAmE;QACpF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,MAAM,KAAK,GAAG,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;QACnD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE;YAC/B,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,CAAC,IAAU;QACf,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7E,IAAI,CAAC;gBACH,IAAI,EAAE,CAAC;YACT,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,QAAQ,CAAC,MAAM;YAAE,MAAM,IAAI,cAAc,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAAC;IACtF,CAAC;IACO,UAAU;QAChB,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAChE,CAAC;IACO,UAAU,CAAC,IAAU;QAC3B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IACE,CAAC,WAAW,CAAC,IAAI,CAAC;YAClB,IAAI,CAAC,WAAW;YAChB,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO;YACrC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YAE1C,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;IAChE,CAAC;IACO,QAAQ,CAAC,OAAyB;QACxC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;YACzC,MAAM,IAAI,SAAS,CAAC,qCAAqC,CAAC,CAAC;QAC7D,KAAK,MAAM,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACrF,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;YACnF,MAAM,IAAI,SAAS,CAAC,2BAA2B,CAAC,CAAC;QACnD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;YACnF,MAAM,IAAI,SAAS,CAAC,0BAA0B,CAAC,CAAC;QAClD,IACE,OAAO,CAAC,MAAM,KAAK,SAAS;YAC5B,CAAC,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAE9D,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;QAC3D,IACE,OAAO,CAAC,WAAW,KAAK,SAAS;YACjC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC;YAElE,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC,CAAC;IACtE,CAAC;IACO,gBAAgB,CAAC,QAA2B;QAClD,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ;YAC3F,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;QACnE,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;YACxB,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC9B,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IACE,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC;YAC/B,MAAM,CAAC,WAAW;YAClB,MAAM,KAAK,IAAI,CAAC,OAAO;YACvB,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO;YACvC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC5C,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC;YAEtC,MAAM,IAAI,SAAS,CACjB,6EAA6E,CAC9E,CAAC;QACJ,KAAK,IAAI,IAAI,GAAmB,MAAM,EAAE,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM;YACvF,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;gBACtC,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAC;QAC1E,cAAc,CAAC,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC;IAC5C,CAAC;IACO,OAAO,CAAC,OAAgB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAkB;QACpE,4FAA4F;QAC5F,OAAO;YACL,IAAI;YACJ,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SACvF,CAAC,IAAI,CACJ,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,KAAK,OAAO;YAChB,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YACpC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CACvC,CAAC;IACJ,CAAC;IACO,KAAK,CAAC,KAAqB;QACjC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QACnC,KAAK,MAAM,QAAQ,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC;YACjC,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,QAAQ,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;oBACtF,OAAO,KAAK,CAAC;gBACf,IAAI,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAC9C,MAAM,IAAI,SAAS,CAAC,kDAAkD,CAAC,CAAC;YAC5E,CAAC;QACH,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,EAC7B,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,CAAC;QAC7C,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAC3C,MAAM,CAAC,GAAG,QAAQ,CAChB,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC7E,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CACrB,CACF,CAAC;QACF,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IACO,IAAI,CAAS,KAAa,EAAE,GAAiB;QACnD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9E,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,CAAC;YAAC,OAAO,OAAO,EAAE,CAAC;gBACjB,MAAM,IAAI,cAAc,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,oCAAoC,CAAC,CAAC;YACnF,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,KAAK,CAAC,GAAG,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
1
+ {"version":3,"file":"connectors.js","sourceRoot":"","sources":["../src/connectors.ts"],"names":[],"mappings":"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"}
package/dist/editor.d.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  import type { AnyNode, Svg } from '@rasamjs/core';
2
2
  import { Connectors } from './connectors.js';
3
+ import type { ConnectorOptions } from './types.js';
4
+ /** One registered connector tool; its id is also its command id. */
5
+ export interface ConnectorEditingTool extends Pick<ConnectorOptions, 'routing' | 'arrows'> {
6
+ readonly id: string;
7
+ readonly label: string;
8
+ readonly key: string;
9
+ readonly hint?: string;
10
+ }
3
11
  export interface ConnectorScope {
4
12
  readonly drawing: Svg;
5
13
  readonly editor: {
@@ -35,7 +43,13 @@ export interface ConnectorScope {
35
43
  created(node: AnyNode): void;
36
44
  exit(): void;
37
45
  }
38
- export declare function connectorEditing(): {
46
+ /**
47
+ * The connectors service and its tools. `tools` replaces the default Connector (`C`)
48
+ * and Elbow connector (`Shift+C`), for example with a Wire tool without arrows.
49
+ */
50
+ export declare function connectorEditing(options?: {
51
+ readonly tools?: readonly ConnectorEditingTool[];
52
+ }): {
39
53
  id: string;
40
54
  create(scope: ConnectorScope): Connectors;
41
55
  };
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,KAAK,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC;QAC1E,QAAQ,CAAC,SAAS,EAAE;YAAE,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;SAAE,CAAC;QAC1D,QAAQ,CAAC,MAAM,EAAE;YAAE,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;SAAE,CAAC;QAC1D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;KAC5C,CAAC;IACF,GAAG,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC;IAC5D,YAAY,CAAC,UAAU,EAAE;QACvB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG;YAAE,OAAO,IAAI,IAAI,CAAC;YAAC,GAAG,CAAC,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAA;SAAE,CAAC;KAC3F,GAAG,MAAM,IAAI,CAAC;IACf,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACpC,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACzD,OAAO,IAAI,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,IAAI,IAAI,IAAI,CAAC;CACd;AACD,wBAAgB,gBAAgB;IAE5B,EAAE;IACF,MAAM,QAAQ,cAAc;EAmD/B"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,oEAAoE;AACpE,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,QAAQ,CAAC;IACxF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,KAAK,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC;QAC1E,QAAQ,CAAC,SAAS,EAAE;YAAE,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;SAAE,CAAC;QAC1D,QAAQ,CAAC,MAAM,EAAE;YAAE,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;SAAE,CAAC;QAC1D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;KAC5C,CAAC;IACF,GAAG,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC;IAC5D,YAAY,CAAC,UAAU,EAAE;QACvB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG;YAAE,OAAO,IAAI,IAAI,CAAC;YAAC,GAAG,CAAC,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAA;SAAE,CAAC;KAC3F,GAAG,MAAM,IAAI,CAAC;IACf,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACpC,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACzD,OAAO,IAAI,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,IAAI,IAAI,IAAI,CAAC;CACd;AACD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAA;CAAO;IAKhE,EAAE;IACF,MAAM,QAAQ,cAAc;EAqD/B"}
package/dist/editor.js CHANGED
@@ -1,23 +1,35 @@
1
1
  import { Connectors } from './connectors.js';
2
2
  import { ConnectorTool } from './tool.js';
3
- export function connectorEditing() {
3
+ const defaultTools = [
4
+ { id: 'connector-straight', label: 'Connector', key: 'C', routing: 'straight' },
5
+ { id: 'connector-elbow', label: 'Elbow connector', key: 'Shift+C', routing: 'elbow' },
6
+ ];
7
+ /**
8
+ * The connectors service and its tools. `tools` replaces the default Connector (`C`)
9
+ * and Elbow connector (`Shift+C`), for example with a Wire tool without arrows.
10
+ */
11
+ export function connectorEditing(options = {}) {
12
+ const tools = options.tools ?? defaultTools;
13
+ if (!Array.isArray(tools))
14
+ throw new TypeError('Connector tools must be an array');
4
15
  return {
5
16
  id: 'connectors',
6
17
  create(scope) {
7
18
  const service = scope.use(new Connectors(scope.drawing));
8
- for (const routing of ['straight', 'elbow'])
19
+ for (const { id, label, key, routing = 'straight', arrows, hint } of tools)
9
20
  scope.registerTool({
10
- id: `connector-${routing}`,
11
- commandId: `connector-${routing}`,
12
- label: routing === 'straight' ? 'Connector' : 'Elbow connector',
13
- key: routing === 'straight' ? 'C' : 'Shift+C',
14
- hint: 'Drag between shapes to connect; hover to choose an anchor; Escape cancels.',
21
+ id,
22
+ commandId: id,
23
+ label,
24
+ key,
25
+ hint: hint ?? 'Drag between shapes to connect; hover to choose an anchor; Escape cancels.',
15
26
  activate(current) {
16
27
  const editor = current.editor;
17
28
  let release = () => { }, dragging = false;
18
29
  current.cleanup(() => release());
19
30
  const tool = current.use(new ConnectorTool(service, {
20
31
  routing,
32
+ arrows,
21
33
  ...editor.paint,
22
34
  selectable: (node) => editor.selection.canSelect(node) && editor.layers.isSelectable(node),
23
35
  onGesture(active) {
@@ -1 +1 @@
1
- {"version":3,"file":"editor.js","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAyB1C,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,EAAE,EAAE,YAAY;QAChB,MAAM,CAAC,KAAqB;YAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YACzD,KAAK,MAAM,OAAO,IAAI,CAAC,UAAU,EAAE,OAAO,CAAU;gBAClD,KAAK,CAAC,YAAY,CAAC;oBACjB,EAAE,EAAE,aAAa,OAAO,EAAE;oBAC1B,SAAS,EAAE,aAAa,OAAO,EAAE;oBACjC,KAAK,EAAE,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB;oBAC/D,GAAG,EAAE,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;oBAC7C,IAAI,EAAE,4EAA4E;oBAClF,QAAQ,CAAC,OAAO;wBACd,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;wBAC9B,IAAI,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,EACpB,QAAQ,GAAG,KAAK,CAAC;wBACnB,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;wBACjC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CACtB,IAAI,aAAa,CAAC,OAAO,EAAE;4BACzB,OAAO;4BACP,GAAG,MAAM,CAAC,KAAK;4BACf,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CACnB,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC;4BACtE,SAAS,CAAC,MAAM;gCACd,QAAQ,GAAG,MAAM,CAAC;gCAClB,OAAO,EAAE,CAAC;gCACV,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;4BAClD,CAAC;4BACD,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;4BACzC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gCACjB,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;gCACrC,OAAO,CAAC,IAAI,EAAE,CAAC;4BACjB,CAAC;4BACD,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE;yBAC7B,CAAC,CACH,CAAC;wBACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;wBAC1C,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;4BACvB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;wBAC5B,CAAC,CAAC,CAAC;wBACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;wBACpB,OAAO;4BACL,OAAO,KAAI,CAAC;4BACZ,GAAG,CAAC,KAAoB;gCACtB,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,QAAQ;oCAAE,OAAO,KAAK,CAAC;gCAClF,IAAI,CAAC,MAAM,EAAE,CAAC;gCACd,OAAO,IAAI,CAAC;4BACd,CAAC;yBACF,CAAC;oBACJ,CAAC;iBACF,CAAC,CAAC;YACL,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"editor.js","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAU1C,MAAM,YAAY,GAAoC;IACpD,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE;IAC/E,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE;CACtF,CAAC;AAyBF;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAO,GAAyD,EAAE;IAElE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;IAC5C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAC;IACnF,OAAO;QACL,EAAE,EAAE,YAAY;QAChB,MAAM,CAAC,KAAqB;YAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YACzD,KAAK,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,GAAG,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK;gBACxE,KAAK,CAAC,YAAY,CAAC;oBACjB,EAAE;oBACF,SAAS,EAAE,EAAE;oBACb,KAAK;oBACL,GAAG;oBACH,IAAI,EACF,IAAI,IAAI,4EAA4E;oBACtF,QAAQ,CAAC,OAAO;wBACd,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;wBAC9B,IAAI,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,EACpB,QAAQ,GAAG,KAAK,CAAC;wBACnB,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;wBACjC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CACtB,IAAI,aAAa,CAAC,OAAO,EAAE;4BACzB,OAAO;4BACP,MAAM;4BACN,GAAG,MAAM,CAAC,KAAK;4BACf,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CACnB,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC;4BACtE,SAAS,CAAC,MAAM;gCACd,QAAQ,GAAG,MAAM,CAAC;gCAClB,OAAO,EAAE,CAAC;gCACV,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;4BAClD,CAAC;4BACD,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;4BACzC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gCACjB,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;gCACrC,OAAO,CAAC,IAAI,EAAE,CAAC;4BACjB,CAAC;4BACD,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE;yBAC7B,CAAC,CACH,CAAC;wBACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;wBAC1C,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;4BACvB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;wBAC5B,CAAC,CAAC,CAAC;wBACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;wBACpB,OAAO;4BACL,OAAO,KAAI,CAAC;4BACZ,GAAG,CAAC,KAAoB;gCACtB,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,QAAQ;oCAAE,OAAO,KAAK,CAAC;gCAClF,IAAI,CAAC,MAAM,EAAE,CAAC;gCACd,OAAO,IAAI,CAAC;4BACd,CAAC;yBACF,CAAC;oBACJ,CAAC;iBACF,CAAC,CAAC;YACL,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,7 +1,11 @@
1
1
  import { Path } from '@rasamjs/core';
2
- import type { AnyNode } from '@rasamjs/core';
3
- import type { ConnectorState } from './types.js';
2
+ import type { AnyNode, Point } from '@rasamjs/core';
3
+ import type { ConnectorEndpoint, ConnectorState } from './types.js';
4
4
  export declare const endpointAttribute: (end: 'start' | 'end') => string;
5
+ /** Loose ends read from a path whose saved target is missing, such as a pasted copy. */
6
+ export declare const unbound: WeakSet<ConnectorEndpoint>;
7
+ /** Where the routed path ends now, in drawing units. */
8
+ export declare function pathEnd(path: Path, end: 'start' | 'end'): Point | null;
5
9
  export declare function isConnector(node: AnyNode): node is Path;
6
10
  export declare function readConnector(path: Path): ConnectorState;
7
11
  export declare function writeConnector(path: Path, state: Omit<ConnectorState, 'path'>): void;
@@ -1 +1 @@
1
- {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAIV,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,iBAAiB,QAAS,OAAO,GAAG,KAAK,WAAkC,CAAC;AAYzF,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,IAAI,CAEvD;AACD,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,cAAc,CAsBxD;AACD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,IAAI,CAcpF"}
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAEV,iBAAiB,EAEjB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,iBAAiB,QAAS,OAAO,GAAG,KAAK,WAAkC,CAAC;AAQzF,wFAAwF;AACxF,eAAO,MAAM,OAAO,4BAAmC,CAAC;AACxD,wDAAwD;AACxD,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,CAOtE;AAOD,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,IAAI,CAEvD;AACD,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,cAAc,CAgCxD;AACD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,IAAI,CAgBpF"}
package/dist/metadata.js CHANGED
@@ -3,6 +3,18 @@ import { data } from '@rasamjs/core/data';
3
3
  import { validateAnchor, validatePoint } from './routing.js';
4
4
  export const endpointAttribute = (end) => `data-rasam-connector-${end}`;
5
5
  const metadataKey = 'rasam-connector';
6
+ /** Loose ends read from a path whose saved target is missing, such as a pasted copy. */
7
+ export const unbound = new WeakSet();
8
+ /** Where the routed path ends now, in drawing units. */
9
+ export function pathEnd(path, end) {
10
+ const values = String(path.getAttributeValue('d') ?? '')
11
+ .match(/[-+]?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?/gi)
12
+ ?.map(Number);
13
+ if (!values || values.length < 4)
14
+ return null;
15
+ const index = end === 'start' ? 0 : values.length - 2;
16
+ return path.worldMatrix().apply({ x: values[index], y: values[index + 1] });
17
+ }
6
18
  export function isConnector(node) {
7
19
  return node instanceof Path && node.getAttributeValue('data-rasam-connector') !== undefined;
8
20
  }
@@ -19,8 +31,19 @@ export function readConnector(path) {
19
31
  return { point: { ...value.point } };
20
32
  }
21
33
  const target = path.references.get(endpointAttribute(end));
22
- if (!target || !('toRoot' in target))
23
- throw new TypeError('Connector endpoint has no bound target');
34
+ if (!target || !('toRoot' in target)) {
35
+ const point = pathEnd(path, end);
36
+ if (!point)
37
+ throw new TypeError('Connector endpoint has no bound target');
38
+ const loose = { point };
39
+ unbound.add(loose);
40
+ return loose;
41
+ }
42
+ if (value.port !== undefined) {
43
+ if (typeof value.port !== 'string' || !value.port)
44
+ throw new TypeError('Invalid connector port metadata');
45
+ return { target: target, port: value.port };
46
+ }
24
47
  validateAnchor(value.anchor ?? 'auto');
25
48
  return {
26
49
  target: target,
@@ -35,7 +58,9 @@ export function writeConnector(path, state) {
35
58
  path.reference(endpointAttribute(end), 'target' in endpoint ? endpoint.target : null, 'href');
36
59
  return 'point' in endpoint
37
60
  ? { point: { ...endpoint.point } }
38
- : { anchor: endpoint.anchor ?? 'auto' };
61
+ : 'port' in endpoint
62
+ ? { port: endpoint.port }
63
+ : { anchor: endpoint.anchor ?? 'auto' };
39
64
  };
40
65
  data(path, metadataKey, {
41
66
  version: 1,