@prnt/dagr-explorer 0.1.3
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/CHANGELOG.md +93 -0
- package/LICENSE +21 -0
- package/README.md +441 -0
- package/dist/base.d.ts +63 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +20 -0
- package/dist/base.js.map +1 -0
- package/dist/camera.d.ts +61 -0
- package/dist/camera.d.ts.map +1 -0
- package/dist/camera.js +142 -0
- package/dist/camera.js.map +1 -0
- package/dist/context.d.ts +110 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +71 -0
- package/dist/context.js.map +1 -0
- package/dist/dagr-explorer.d.ts +41 -0
- package/dist/dagr-explorer.d.ts.map +1 -0
- package/dist/dagr-explorer.js +13 -0
- package/dist/dagr-explorer.js.map +1 -0
- package/dist/errors.d.ts +55 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +57 -0
- package/dist/errors.js.map +1 -0
- package/dist/explorer-details.d.ts +44 -0
- package/dist/explorer-details.d.ts.map +1 -0
- package/dist/explorer-details.js +76 -0
- package/dist/explorer-details.js.map +1 -0
- package/dist/explorer-search.d.ts +31 -0
- package/dist/explorer-search.d.ts.map +1 -0
- package/dist/explorer-search.js +86 -0
- package/dist/explorer-search.js.map +1 -0
- package/dist/explorer-toolbar.d.ts +17 -0
- package/dist/explorer-toolbar.d.ts.map +1 -0
- package/dist/explorer-toolbar.js +44 -0
- package/dist/explorer-toolbar.js.map +1 -0
- package/dist/explorer-trace-toggle.d.ts +16 -0
- package/dist/explorer-trace-toggle.d.ts.map +1 -0
- package/dist/explorer-trace-toggle.js +8 -0
- package/dist/explorer-trace-toggle.js.map +1 -0
- package/dist/explorer-viewport.d.ts +69 -0
- package/dist/explorer-viewport.d.ts.map +1 -0
- package/dist/explorer-viewport.js +69 -0
- package/dist/explorer-viewport.js.map +1 -0
- package/dist/explorer-views.d.ts +24 -0
- package/dist/explorer-views.d.ts.map +1 -0
- package/dist/explorer-views.js +16 -0
- package/dist/explorer-views.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/isomorphic-layout-effect.d.ts +7 -0
- package/dist/isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/isomorphic-layout-effect.js +7 -0
- package/dist/isomorphic-layout-effect.js.map +1 -0
- package/dist/labels.d.ts +67 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +50 -0
- package/dist/labels.js.map +1 -0
- package/dist/layout.d.ts +82 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +244 -0
- package/dist/layout.js.map +1 -0
- package/dist/navigation.d.ts +20 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +44 -0
- package/dist/navigation.js.map +1 -0
- package/dist/root.d.ts +89 -0
- package/dist/root.d.ts.map +1 -0
- package/dist/root.js +401 -0
- package/dist/root.js.map +1 -0
- package/dist/search.d.ts +19 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +31 -0
- package/dist/search.js.map +1 -0
- package/dist/size.d.ts +12 -0
- package/dist/size.d.ts.map +1 -0
- package/dist/size.js +20 -0
- package/dist/size.js.map +1 -0
- package/dist/svg-base.d.ts +33 -0
- package/dist/svg-base.d.ts.map +1 -0
- package/dist/svg-base.js +89 -0
- package/dist/svg-base.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/use-explorer-camera.d.ts +56 -0
- package/dist/use-explorer-camera.d.ts.map +1 -0
- package/dist/use-explorer-camera.js +641 -0
- package/dist/use-explorer-camera.js.map +1 -0
- package/dist/use-explorer.d.ts +23 -0
- package/dist/use-explorer.d.ts.map +1 -0
- package/dist/use-explorer.js +26 -0
- package/dist/use-explorer.js.map +1 -0
- package/dist/validate.d.ts +20 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +99 -0
- package/dist/validate.js.map +1 -0
- package/dist/viewport-surface.d.ts +90 -0
- package/dist/viewport-surface.d.ts.map +1 -0
- package/dist/viewport-surface.js +485 -0
- package/dist/viewport-surface.js.map +1 -0
- package/dist/visible-set.d.ts +65 -0
- package/dist/visible-set.d.ts.map +1 -0
- package/dist/visible-set.js +168 -0
- package/dist/visible-set.js.map +1 -0
- package/package.json +62 -0
- package/src/base.ts +67 -0
- package/src/camera.ts +206 -0
- package/src/context.ts +168 -0
- package/src/dagr-explorer.tsx +85 -0
- package/src/errors.ts +85 -0
- package/src/explorer-details.tsx +156 -0
- package/src/explorer-search.tsx +140 -0
- package/src/explorer-toolbar.tsx +77 -0
- package/src/explorer-trace-toggle.tsx +34 -0
- package/src/explorer-viewport.tsx +181 -0
- package/src/explorer-views.tsx +61 -0
- package/src/index.ts +76 -0
- package/src/isomorphic-layout-effect.ts +7 -0
- package/src/labels.ts +109 -0
- package/src/layout.ts +298 -0
- package/src/navigation.ts +51 -0
- package/src/root.tsx +544 -0
- package/src/search.ts +36 -0
- package/src/size.ts +23 -0
- package/src/svg-base.tsx +173 -0
- package/src/types.ts +69 -0
- package/src/use-explorer-camera.ts +675 -0
- package/src/use-explorer.ts +32 -0
- package/src/validate.ts +173 -0
- package/src/viewport-surface.tsx +650 -0
- package/src/visible-set.ts +225 -0
- package/styles.css +253 -0
package/dist/camera.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The camera's arithmetic, with no DOM and no clock.
|
|
3
|
+
*
|
|
4
|
+
* A camera is the plane's CSS transform: `translate(x, y) scale(scale)`, in
|
|
5
|
+
* CSS pixels, over a world that is y-down. Everything here is a pure function
|
|
6
|
+
* from a camera to a camera, so the hook that owns the animation frame holds
|
|
7
|
+
* no arithmetic of its own and all of it is testable in Node.
|
|
8
|
+
*
|
|
9
|
+
* **Functions return the camera that was ASKED for, not the one allowed.**
|
|
10
|
+
* `CameraLimits.constrain` is the one place a camera is clamped, and the
|
|
11
|
+
* caller decides when: a target is constrained when it is set, and the eased
|
|
12
|
+
* camera again when it is drawn, so a flight can cross a sparse gap without
|
|
13
|
+
* being trapped against the nearest node on the way.
|
|
14
|
+
*
|
|
15
|
+
* Limits come from `Camera2D` in `@prnt/dagr-render/core`, which speaks a
|
|
16
|
+
* y-up world with a center and a zoom. The conversion to and from this
|
|
17
|
+
* module's top-left, y-down camera lives in `createCameraLimits` and nowhere
|
|
18
|
+
* else.
|
|
19
|
+
*
|
|
20
|
+
* Internal to the package. Only the `ExplorerCamera` type is exported from
|
|
21
|
+
* the entry, because `ExplorerCameraSource` hands one out.
|
|
22
|
+
*/
|
|
23
|
+
import type { ExplorerBox, ExplorerLayout } from './layout.js';
|
|
24
|
+
import type { Vec2 } from '@prnt/dagr-render/core';
|
|
25
|
+
export interface ExplorerCamera {
|
|
26
|
+
readonly x: number;
|
|
27
|
+
readonly y: number;
|
|
28
|
+
readonly scale: number;
|
|
29
|
+
}
|
|
30
|
+
export interface ExplorerViewportSize {
|
|
31
|
+
readonly width: number;
|
|
32
|
+
readonly height: number;
|
|
33
|
+
}
|
|
34
|
+
export interface CameraLimits {
|
|
35
|
+
readonly minScale: number;
|
|
36
|
+
readonly maxScale: number;
|
|
37
|
+
/**
|
|
38
|
+
* Throws a `RangeError` for a camera whose `scale` is not a positive finite
|
|
39
|
+
* number or whose `x` or `y` is not finite, because `Camera2D` validates
|
|
40
|
+
* what it is given. Callers hold cameras that came from these functions.
|
|
41
|
+
*/
|
|
42
|
+
constrain(camera: ExplorerCamera): ExplorerCamera;
|
|
43
|
+
}
|
|
44
|
+
export declare const CONTENT_PADDING = 0.05;
|
|
45
|
+
export declare const FOCUS_MARGIN = 24;
|
|
46
|
+
export declare const REVEAL_MARGIN = 12;
|
|
47
|
+
export declare const EASE_MS = 55;
|
|
48
|
+
export declare function createCameraLimits(layout: ExplorerLayout, viewport: ExplorerViewportSize): CameraLimits | null;
|
|
49
|
+
export declare function fitCamera(layout: ExplorerLayout, viewport: ExplorerViewportSize, limits: CameraLimits): ExplorerCamera;
|
|
50
|
+
/** Divides by `camera.scale`: expects a positive scale, as every camera from `fitCamera` and `constrain` has. */
|
|
51
|
+
export declare function zoomCamera(camera: ExplorerCamera, factor: number, anchor: Vec2, limits: CameraLimits): ExplorerCamera;
|
|
52
|
+
export declare function panCamera(camera: ExplorerCamera, dx: number, dy: number): ExplorerCamera;
|
|
53
|
+
export declare function focusCamera(box: ExplorerBox, viewport: ExplorerViewportSize, limits: CameraLimits): ExplorerCamera;
|
|
54
|
+
export declare function revealCamera(camera: ExplorerCamera, box: ExplorerBox, viewport: ExplorerViewportSize): ExplorerCamera;
|
|
55
|
+
/** Divides by `camera.scale`: expects a positive scale, as every camera from `fitCamera` and `constrain` has. */
|
|
56
|
+
export declare function visibleWorld(camera: ExplorerCamera, viewport: ExplorerViewportSize): ExplorerBox;
|
|
57
|
+
/** Divides by `camera.scale`: expects a positive scale, as every camera from `fitCamera` and `constrain` has. */
|
|
58
|
+
export declare function screenToWorld(camera: ExplorerCamera, point: Vec2): Vec2;
|
|
59
|
+
export declare function easeCamera(current: ExplorerCamera, target: ExplorerCamera, elapsedMs: number): ExplorerCamera;
|
|
60
|
+
export declare function cameraSettled(current: ExplorerCamera, target: ExplorerCamera): boolean;
|
|
61
|
+
//# sourceMappingURL=camera.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AACD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAAC;CACnD;AAED,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,OAAO,KAAK,CAAC;AAE1B,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,oBAAoB,GAC7B,YAAY,GAAG,IAAI,CA6CrB;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,EAAE,YAAY,GACnB,cAAc,CAOhB;AAED,iHAAiH;AACjH,wBAAgB,UAAU,CACxB,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,YAAY,GACnB,cAAc,CAQhB;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,cAAc,CAExF;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,EAAE,YAAY,GACnB,cAAc,CAWhB;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,oBAAoB,GAC7B,cAAc,CAchB;AAED,iHAAiH;AACjH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,oBAAoB,GAAG,WAAW,CAOhG;AAED,iHAAiH;AACjH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,CAEvE;AAED,wBAAgB,UAAU,CACxB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,GAChB,cAAc,CAOhB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAKtF"}
|
package/dist/camera.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The camera's arithmetic, with no DOM and no clock.
|
|
3
|
+
*
|
|
4
|
+
* A camera is the plane's CSS transform: `translate(x, y) scale(scale)`, in
|
|
5
|
+
* CSS pixels, over a world that is y-down. Everything here is a pure function
|
|
6
|
+
* from a camera to a camera, so the hook that owns the animation frame holds
|
|
7
|
+
* no arithmetic of its own and all of it is testable in Node.
|
|
8
|
+
*
|
|
9
|
+
* **Functions return the camera that was ASKED for, not the one allowed.**
|
|
10
|
+
* `CameraLimits.constrain` is the one place a camera is clamped, and the
|
|
11
|
+
* caller decides when: a target is constrained when it is set, and the eased
|
|
12
|
+
* camera again when it is drawn, so a flight can cross a sparse gap without
|
|
13
|
+
* being trapped against the nearest node on the way.
|
|
14
|
+
*
|
|
15
|
+
* Limits come from `Camera2D` in `@prnt/dagr-render/core`, which speaks a
|
|
16
|
+
* y-up world with a center and a zoom. The conversion to and from this
|
|
17
|
+
* module's top-left, y-down camera lives in `createCameraLimits` and nowhere
|
|
18
|
+
* else.
|
|
19
|
+
*
|
|
20
|
+
* Internal to the package. Only the `ExplorerCamera` type is exported from
|
|
21
|
+
* the entry, because `ExplorerCameraSource` hands one out.
|
|
22
|
+
*/
|
|
23
|
+
import { Camera2D, fitZoom } from '@prnt/dagr-render/core';
|
|
24
|
+
export const CONTENT_PADDING = 0.05;
|
|
25
|
+
export const FOCUS_MARGIN = 24;
|
|
26
|
+
export const REVEAL_MARGIN = 12;
|
|
27
|
+
export const EASE_MS = 55;
|
|
28
|
+
export function createCameraLimits(layout, viewport) {
|
|
29
|
+
if (!(viewport.width > 0) || !(viewport.height > 0) || !(layout.width > 0) || !(layout.height > 0)) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const limiter = new Camera2D({
|
|
33
|
+
viewport: { width: viewport.width, height: viewport.height, devicePixelRatio: 1 },
|
|
34
|
+
});
|
|
35
|
+
let detail = { width: 160, height: 80 };
|
|
36
|
+
let best = 0;
|
|
37
|
+
const regions = [];
|
|
38
|
+
for (const box of layout.boxes.values()) {
|
|
39
|
+
const zoom = fitZoom({ minX: 0, minY: 0, maxX: box.width, maxY: box.height }, limiter.viewport);
|
|
40
|
+
if (zoom > best) {
|
|
41
|
+
best = zoom;
|
|
42
|
+
detail = { width: box.width, height: box.height };
|
|
43
|
+
}
|
|
44
|
+
regions.push({
|
|
45
|
+
minX: box.x,
|
|
46
|
+
maxX: box.x + box.width,
|
|
47
|
+
minY: -box.y - box.height,
|
|
48
|
+
maxY: -box.y,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
limiter.setContentBounds({ minX: 0, maxX: layout.width, minY: -layout.height, maxY: 0 }, detail, CONTENT_PADDING, regions);
|
|
52
|
+
return {
|
|
53
|
+
minScale: limiter.minZoom,
|
|
54
|
+
maxScale: limiter.maxZoom,
|
|
55
|
+
constrain(camera) {
|
|
56
|
+
limiter.setZoom(camera.scale);
|
|
57
|
+
limiter.setCenter({
|
|
58
|
+
x: (viewport.width / 2 - camera.x) / limiter.zoom,
|
|
59
|
+
y: -(viewport.height / 2 - camera.y) / limiter.zoom,
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
x: viewport.width / 2 - limiter.center.x * limiter.zoom,
|
|
63
|
+
y: viewport.height / 2 + limiter.center.y * limiter.zoom,
|
|
64
|
+
scale: limiter.zoom,
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export function fitCamera(layout, viewport, limits) {
|
|
70
|
+
const scale = limits.minScale;
|
|
71
|
+
return {
|
|
72
|
+
x: (viewport.width - layout.width * scale) / 2,
|
|
73
|
+
y: (viewport.height - layout.height * scale) / 2,
|
|
74
|
+
scale,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** Divides by `camera.scale`: expects a positive scale, as every camera from `fitCamera` and `constrain` has. */
|
|
78
|
+
export function zoomCamera(camera, factor, anchor, limits) {
|
|
79
|
+
const scale = Math.max(limits.minScale, Math.min(limits.maxScale, camera.scale * factor));
|
|
80
|
+
const ratio = scale / camera.scale;
|
|
81
|
+
return {
|
|
82
|
+
x: anchor.x - (anchor.x - camera.x) * ratio,
|
|
83
|
+
y: anchor.y - (anchor.y - camera.y) * ratio,
|
|
84
|
+
scale,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function panCamera(camera, dx, dy) {
|
|
88
|
+
return { x: camera.x + dx, y: camera.y + dy, scale: camera.scale };
|
|
89
|
+
}
|
|
90
|
+
export function focusCamera(box, viewport, limits) {
|
|
91
|
+
const fill = Math.min((viewport.width - FOCUS_MARGIN * 2) / box.width, (viewport.height - FOCUS_MARGIN * 2) / box.height);
|
|
92
|
+
const scale = Math.max(limits.minScale, Math.min(limits.maxScale, fill));
|
|
93
|
+
return {
|
|
94
|
+
x: viewport.width / 2 - (box.x + box.width / 2) * scale,
|
|
95
|
+
y: viewport.height / 2 - (box.y + box.height / 2) * scale,
|
|
96
|
+
scale,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export function revealCamera(camera, box, viewport) {
|
|
100
|
+
const axis = (offset, start, size, extent) => {
|
|
101
|
+
const lo = offset + start * camera.scale;
|
|
102
|
+
const hi = lo + size * camera.scale;
|
|
103
|
+
if (hi - lo > extent - REVEAL_MARGIN * 2)
|
|
104
|
+
return offset + (extent / 2 - (lo + hi) / 2);
|
|
105
|
+
if (lo < REVEAL_MARGIN)
|
|
106
|
+
return offset + (REVEAL_MARGIN - lo);
|
|
107
|
+
if (hi > extent - REVEAL_MARGIN)
|
|
108
|
+
return offset + (extent - REVEAL_MARGIN - hi);
|
|
109
|
+
return offset;
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
x: axis(camera.x, box.x, box.width, viewport.width),
|
|
113
|
+
y: axis(camera.y, box.y, box.height, viewport.height),
|
|
114
|
+
scale: camera.scale,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/** Divides by `camera.scale`: expects a positive scale, as every camera from `fitCamera` and `constrain` has. */
|
|
118
|
+
export function visibleWorld(camera, viewport) {
|
|
119
|
+
return {
|
|
120
|
+
x: -camera.x / camera.scale,
|
|
121
|
+
y: -camera.y / camera.scale,
|
|
122
|
+
width: viewport.width / camera.scale,
|
|
123
|
+
height: viewport.height / camera.scale,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** Divides by `camera.scale`: expects a positive scale, as every camera from `fitCamera` and `constrain` has. */
|
|
127
|
+
export function screenToWorld(camera, point) {
|
|
128
|
+
return { x: (point.x - camera.x) / camera.scale, y: (point.y - camera.y) / camera.scale };
|
|
129
|
+
}
|
|
130
|
+
export function easeCamera(current, target, elapsedMs) {
|
|
131
|
+
const alpha = 1 - Math.exp(-Math.max(0, Math.min(64, elapsedMs)) / EASE_MS);
|
|
132
|
+
return {
|
|
133
|
+
x: current.x + (target.x - current.x) * alpha,
|
|
134
|
+
y: current.y + (target.y - current.y) * alpha,
|
|
135
|
+
scale: current.scale + (target.scale - current.scale) * alpha,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
export function cameraSettled(current, target) {
|
|
139
|
+
return (Math.abs(current.x - target.x) + Math.abs(current.y - target.y) < 0.05 &&
|
|
140
|
+
Math.abs(current.scale - target.scale) < 0.0001);
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=camera.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera.js","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contexts the parts talk through, and the public shapes they carry.
|
|
3
|
+
*
|
|
4
|
+
* `ExplorerRoot` provides two. The api context holds only the stable
|
|
5
|
+
* `ExplorerApi`, and its value never changes, so a component that only calls
|
|
6
|
+
* methods (`useExplorerApi()`) never re-renders for a keystroke. The main
|
|
7
|
+
* context holds two things:
|
|
8
|
+
* the state a host may read and the methods it may call (`useExplorer()`
|
|
9
|
+
* returns exactly that), and a few internals only the built-in parts use to
|
|
10
|
+
* wire themselves to the root: the viewport's registration, its camera
|
|
11
|
+
* controls, and the elements focus is restored to.
|
|
12
|
+
*
|
|
13
|
+
* **The type parameters are a claim, not a check.** A context erases them, so
|
|
14
|
+
* the state is stored over the base node and edge types and each part casts
|
|
15
|
+
* to the `N` and `E` it was given. See the spec's Composition section.
|
|
16
|
+
*/
|
|
17
|
+
import type { MutableRefObject } from 'react';
|
|
18
|
+
import type { ExplorerCameraSource } from './base.js';
|
|
19
|
+
import type { ExplorerLabels } from './labels.js';
|
|
20
|
+
import type { ExplorerLayout } from './layout.js';
|
|
21
|
+
import type { ExplorerEdge, ExplorerNode, ExplorerView } from './types.js';
|
|
22
|
+
import type { ExplorerCameraControls } from './use-explorer-camera.js';
|
|
23
|
+
/**
|
|
24
|
+
* Everything a host can do to an explorer. `ExplorerRoot`'s `apiRef` and
|
|
25
|
+
* `useExplorer()` hand out the same functions, stable for the root's life.
|
|
26
|
+
*
|
|
27
|
+
* Under a controlled `viewId` or `selectedId`, a method that would change it
|
|
28
|
+
* calls `onViewChange` or `onSelectedChange` and changes nothing on screen
|
|
29
|
+
* until the prop does. An id the active view lacks is ignored.
|
|
30
|
+
*/
|
|
31
|
+
export interface ExplorerApi {
|
|
32
|
+
/** Fits the whole view. A no-op before a viewport has a size. */
|
|
33
|
+
fit(): void;
|
|
34
|
+
/** Zooms about the viewport center. */
|
|
35
|
+
zoomBy(factor: number): void;
|
|
36
|
+
/** Flies the camera to fit the node. */
|
|
37
|
+
focusNode(id: string): void;
|
|
38
|
+
/** Pans the least distance that brings the node into view, at the current zoom. */
|
|
39
|
+
reveal(id: string): void;
|
|
40
|
+
/** Sets the current node, or clears it. Does not open the drawer. */
|
|
41
|
+
select(id: string | null): void;
|
|
42
|
+
/**
|
|
43
|
+
* Selects the node and opens the drawer on it. `trigger` is the element
|
|
44
|
+
* focus returns to when the drawer closes. Without one, the element that
|
|
45
|
+
* has focus is recorded, unless the drawer is already open, in which case
|
|
46
|
+
* the opener it has is kept: that is how a connection in the drawer
|
|
47
|
+
* inspects its neighbor and `Escape` still returns to the first opener.
|
|
48
|
+
*/
|
|
49
|
+
inspect(id: string, trigger?: HTMLElement | null): void;
|
|
50
|
+
closeDetails(): void;
|
|
51
|
+
/** Switches view. Resets the query, trace, drawer and camera. */
|
|
52
|
+
selectView(id: string): void;
|
|
53
|
+
setQuery(query: string): void;
|
|
54
|
+
setTrace(on: boolean): void;
|
|
55
|
+
}
|
|
56
|
+
/** What `useExplorer()` returns: the explorer's current state, and its methods. */
|
|
57
|
+
export interface ExplorerState<N extends ExplorerNode = ExplorerNode, E extends ExplorerEdge = ExplorerEdge> extends ExplorerApi {
|
|
58
|
+
/** The root's `label`, the accessible name the parts derive theirs from. */
|
|
59
|
+
readonly label: string;
|
|
60
|
+
readonly labels: ExplorerLabels;
|
|
61
|
+
readonly views: readonly ExplorerView<N, E>[];
|
|
62
|
+
/** `null` only when there are no views. */
|
|
63
|
+
readonly activeView: ExplorerView<N, E> | null;
|
|
64
|
+
/** The active view, placed. `null` only when there are no views. */
|
|
65
|
+
readonly layout: ExplorerLayout | null;
|
|
66
|
+
/** The current node, or `null`. Never an id the active view lacks. */
|
|
67
|
+
readonly selectedId: string | null;
|
|
68
|
+
readonly selectedNode: N | null;
|
|
69
|
+
readonly query: string;
|
|
70
|
+
/** The nodes the query matches, in data order. Empty for a blank query. */
|
|
71
|
+
readonly matches: readonly N[];
|
|
72
|
+
readonly trace: boolean;
|
|
73
|
+
/** Whether the drawer is showing the selected node. */
|
|
74
|
+
readonly detailsOpen: boolean;
|
|
75
|
+
/** Node ids drawn dimmed: by the query, by trace, or by both. */
|
|
76
|
+
readonly dimmed: ReadonlySet<string>;
|
|
77
|
+
/** The camera on screen and every frame of it, for a host's own zoom readout. */
|
|
78
|
+
readonly camera: ExplorerCameraSource;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The camera source the root hands out before and after a viewport exists:
|
|
82
|
+
* it forwards to whichever viewport is attached, and stays the same object
|
|
83
|
+
* across a view switch, which remounts the viewport.
|
|
84
|
+
*/
|
|
85
|
+
export interface CameraHub extends ExplorerCameraSource {
|
|
86
|
+
/** Attaches a viewport's source. Returns the detach. */
|
|
87
|
+
attach(source: ExplorerCameraSource): () => void;
|
|
88
|
+
}
|
|
89
|
+
export declare function createCameraHub(): CameraHub;
|
|
90
|
+
/** What only the built-in parts use. Stable for the root's life. */
|
|
91
|
+
export interface ExplorerInternals {
|
|
92
|
+
/** Called from the viewport's effect. Throws `SECOND_VIEWPORT` for a second. */
|
|
93
|
+
registerViewport(): () => void;
|
|
94
|
+
readonly controlsRef: MutableRefObject<ExplorerCameraControls | null>;
|
|
95
|
+
readonly camera: CameraHub;
|
|
96
|
+
/** Where focus goes when the drawer closes and its opener is gone. */
|
|
97
|
+
readonly searchInputRef: MutableRefObject<HTMLInputElement | null>;
|
|
98
|
+
}
|
|
99
|
+
export interface ExplorerContextValue {
|
|
100
|
+
readonly state: ExplorerState;
|
|
101
|
+
readonly internals: ExplorerInternals;
|
|
102
|
+
}
|
|
103
|
+
export declare const ExplorerContext: import("react").Context<ExplorerContextValue | null>;
|
|
104
|
+
/** The root's context, or `OUTSIDE_EXPLORER` naming `part`. */
|
|
105
|
+
export declare function useExplorerContext(part: string): ExplorerContextValue;
|
|
106
|
+
/** The root's stable methods alone. Its value is the same object for the root's life. */
|
|
107
|
+
export declare const ExplorerApiContext: import("react").Context<ExplorerApi | null>;
|
|
108
|
+
/** The root's stable methods, or `OUTSIDE_EXPLORER` naming `part`. */
|
|
109
|
+
export declare function useExplorerApiContext(part: string): ExplorerApi;
|
|
110
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contexts the parts talk through, and the public shapes they carry.
|
|
3
|
+
*
|
|
4
|
+
* `ExplorerRoot` provides two. The api context holds only the stable
|
|
5
|
+
* `ExplorerApi`, and its value never changes, so a component that only calls
|
|
6
|
+
* methods (`useExplorerApi()`) never re-renders for a keystroke. The main
|
|
7
|
+
* context holds two things:
|
|
8
|
+
* the state a host may read and the methods it may call (`useExplorer()`
|
|
9
|
+
* returns exactly that), and a few internals only the built-in parts use to
|
|
10
|
+
* wire themselves to the root: the viewport's registration, its camera
|
|
11
|
+
* controls, and the elements focus is restored to.
|
|
12
|
+
*
|
|
13
|
+
* **The type parameters are a claim, not a check.** A context erases them, so
|
|
14
|
+
* the state is stored over the base node and edge types and each part casts
|
|
15
|
+
* to the `N` and `E` it was given. See the spec's Composition section.
|
|
16
|
+
*/
|
|
17
|
+
import { createContext, useContext } from 'react';
|
|
18
|
+
import { ExplorerContextError } from './errors.js';
|
|
19
|
+
export function createCameraHub() {
|
|
20
|
+
let attached = null;
|
|
21
|
+
const listeners = new Set();
|
|
22
|
+
const emit = (camera) => {
|
|
23
|
+
for (const listener of [...listeners])
|
|
24
|
+
listener(camera);
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
get: () => attached?.get() ?? null,
|
|
28
|
+
subscribe(listener) {
|
|
29
|
+
// Wrapped, so one listener subscribed twice is two subscriptions.
|
|
30
|
+
const own = (camera) => listener(camera);
|
|
31
|
+
listeners.add(own);
|
|
32
|
+
return () => {
|
|
33
|
+
listeners.delete(own);
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
attach(source) {
|
|
37
|
+
attached = source;
|
|
38
|
+
const off = source.subscribe(emit);
|
|
39
|
+
// The viewport drew its first frame before it could be attached, so a
|
|
40
|
+
// readout that subscribed early would otherwise wait for the next one.
|
|
41
|
+
const now = source.get();
|
|
42
|
+
if (now !== null)
|
|
43
|
+
emit(now);
|
|
44
|
+
return () => {
|
|
45
|
+
off();
|
|
46
|
+
if (attached === source)
|
|
47
|
+
attached = null;
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export const ExplorerContext = createContext(null);
|
|
53
|
+
/** The root's context, or `OUTSIDE_EXPLORER` naming `part`. */
|
|
54
|
+
export function useExplorerContext(part) {
|
|
55
|
+
const value = useContext(ExplorerContext);
|
|
56
|
+
if (value === null) {
|
|
57
|
+
throw new ExplorerContextError('OUTSIDE_EXPLORER', `${part} must be used inside an ExplorerRoot`);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
/** The root's stable methods alone. Its value is the same object for the root's life. */
|
|
62
|
+
export const ExplorerApiContext = createContext(null);
|
|
63
|
+
/** The root's stable methods, or `OUTSIDE_EXPLORER` naming `part`. */
|
|
64
|
+
export function useExplorerApiContext(part) {
|
|
65
|
+
const value = useContext(ExplorerApiContext);
|
|
66
|
+
if (value === null) {
|
|
67
|
+
throw new ExplorerContextError('OUTSIDE_EXPLORER', `${part} must be used inside an ExplorerRoot`);
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAIlD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA4EnD,MAAM,UAAU,eAAe;IAC7B,IAAI,QAAQ,GAAgC,IAAI,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoC,CAAC;IAC9D,MAAM,IAAI,GAAG,CAAC,MAAsB,EAAQ,EAAE;QAC5C,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,SAAS,CAAC;YAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC,CAAC;IACF,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,IAAI;QAClC,SAAS,CAAC,QAAQ;YAChB,kEAAkE;YAClE,MAAM,GAAG,GAAG,CAAC,MAAsB,EAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC/D,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,MAAM;YACX,QAAQ,GAAG,MAAM,CAAC;YAClB,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACnC,sEAAsE;YACtE,uEAAuE;YACvE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;YACzB,IAAI,GAAG,KAAK,IAAI;gBAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5B,OAAO,GAAG,EAAE;gBACV,GAAG,EAAE,CAAC;gBACN,IAAI,QAAQ,KAAK,MAAM;oBAAE,QAAQ,GAAG,IAAI,CAAC;YAC3C,CAAC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAiBD,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAA8B,IAAI,CAAC,CAAC;AAEhF,+DAA+D;AAC/D,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,oBAAoB,CAC5B,kBAAkB,EAClB,GAAG,IAAI,sCAAsC,CAC9C,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAqB,IAAI,CAAC,CAAC;AAE1E,sEAAsE;AACtE,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,KAAK,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC7C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,oBAAoB,CAAC,kBAAkB,EAAE,GAAG,IAAI,sCAAsC,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `DagrExplorer`: the explorer, preassembled.
|
|
3
|
+
*
|
|
4
|
+
* It is composed only from the public parts, with no private access, so
|
|
5
|
+
* anything it does a host can do by composing the parts itself. Its props are
|
|
6
|
+
* the root's, plus the parts' slots and options under the names below.
|
|
7
|
+
*
|
|
8
|
+
* `N` and `E` are inferred from `views` (or `nodes` and `edges`), and every
|
|
9
|
+
* slot is typed from them. That is the check hand-composed parts cannot
|
|
10
|
+
* give, because they talk through a context.
|
|
11
|
+
*/
|
|
12
|
+
import type { ReactElement } from 'react';
|
|
13
|
+
import type { ExplorerBase } from './base.js';
|
|
14
|
+
import type { ExplorerDetailsProps } from './explorer-details.js';
|
|
15
|
+
import type { ExplorerViewportProps } from './explorer-viewport.js';
|
|
16
|
+
import type { ExplorerViewsProps } from './explorer-views.js';
|
|
17
|
+
import type { ExplorerRootProps } from './root.js';
|
|
18
|
+
import type { ExplorerEdge, ExplorerNode } from './types.js';
|
|
19
|
+
import type { ExplorerTiers } from './visible-set.js';
|
|
20
|
+
interface DagrExplorerParts<N extends ExplorerNode, E extends ExplorerEdge> {
|
|
21
|
+
/** `ExplorerViewport`'s `renderNode`. */
|
|
22
|
+
readonly renderNode?: ExplorerViewportProps<N>['renderNode'];
|
|
23
|
+
/** `ExplorerViewport`'s `nodeAriaLabel`. */
|
|
24
|
+
readonly nodeAriaLabel?: ExplorerViewportProps<N>['nodeAriaLabel'];
|
|
25
|
+
readonly tiers?: ExplorerTiers | undefined;
|
|
26
|
+
readonly maxOverlayNodes?: number | undefined;
|
|
27
|
+
/** Experimental. See `ExplorerBase`. */
|
|
28
|
+
readonly base?: ExplorerBase | undefined;
|
|
29
|
+
/** `ExplorerDetails`'s children. */
|
|
30
|
+
readonly renderDetails?: ExplorerDetailsProps<N, E>['children'];
|
|
31
|
+
/** `ExplorerDetails`'s `renderConnection`. */
|
|
32
|
+
readonly renderConnection?: ExplorerDetailsProps<N, E>['renderConnection'];
|
|
33
|
+
/** `ExplorerViews`'s children. */
|
|
34
|
+
readonly renderViews?: ExplorerViewsProps<N, E>['children'];
|
|
35
|
+
/** Preassembled: compose the parts to add your own. */
|
|
36
|
+
readonly children?: never;
|
|
37
|
+
}
|
|
38
|
+
export type DagrExplorerProps<N extends ExplorerNode = ExplorerNode, E extends ExplorerEdge = ExplorerEdge> = ExplorerRootProps<N, E> & DagrExplorerParts<N, E>;
|
|
39
|
+
export declare function DagrExplorer<N extends ExplorerNode = ExplorerNode, E extends ExplorerEdge = ExplorerEdge>(props: DagrExplorerProps<N, E>): ReactElement;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=dagr-explorer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dagr-explorer.d.ts","sourceRoot":"","sources":["../src/dagr-explorer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAKlE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,UAAU,iBAAiB,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,YAAY;IACxE,yCAAyC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAC7D,4CAA4C;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IACnE,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACzC,oCAAoC;IACpC,QAAQ,CAAC,aAAa,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAChE,8CAA8C;IAC9C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAC3E,kCAAkC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAC5D,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;CAC3B;AAED,MAAM,MAAM,iBAAiB,CAC3B,CAAC,SAAS,YAAY,GAAG,YAAY,EACrC,CAAC,SAAS,YAAY,GAAG,YAAY,IACnC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEtD,wBAAgB,YAAY,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,CAAC,SAAS,YAAY,GAAG,YAAY,EACvG,KAAK,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,YAAY,CA8Bd"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ExplorerDetails } from './explorer-details.js';
|
|
3
|
+
import { ExplorerSearch } from './explorer-search.js';
|
|
4
|
+
import { ExplorerToolbar } from './explorer-toolbar.js';
|
|
5
|
+
import { ExplorerTraceToggle } from './explorer-trace-toggle.js';
|
|
6
|
+
import { ExplorerViewport } from './explorer-viewport.js';
|
|
7
|
+
import { ExplorerViews } from './explorer-views.js';
|
|
8
|
+
import { ExplorerRoot } from './root.js';
|
|
9
|
+
export function DagrExplorer(props) {
|
|
10
|
+
const { renderNode, nodeAriaLabel, tiers, maxOverlayNodes, base, renderDetails, renderConnection, renderViews, ...root } = props;
|
|
11
|
+
return (_jsxs(ExplorerRoot, { ...root, children: [_jsx(ExplorerViews, { children: renderViews }), _jsx(ExplorerSearch, {}), _jsx(ExplorerTraceToggle, {}), _jsx(ExplorerViewport, { renderNode: renderNode, nodeAriaLabel: nodeAriaLabel, tiers: tiers, maxOverlayNodes: maxOverlayNodes, base: base, children: _jsx(ExplorerDetails, { renderConnection: renderConnection, children: renderDetails }) }), _jsx(ExplorerToolbar, {})] }));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=dagr-explorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dagr-explorer.js","sourceRoot":"","sources":["../src/dagr-explorer.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AA6BzC,MAAM,UAAU,YAAY,CAC1B,KAA8B;IAE9B,MAAM,EACJ,UAAU,EACV,aAAa,EACb,KAAK,EACL,eAAe,EACf,IAAI,EACJ,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IACV,OAAO,CACL,MAAC,YAAY,OAAY,IAAgC,aACvD,KAAC,aAAa,cAAQ,WAAW,GAAiB,EAClD,KAAC,cAAc,KAAG,EAClB,KAAC,mBAAmB,KAAG,EAEvB,KAAC,gBAAgB,IACf,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,KAAK,EACZ,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,IAAI,YAEV,KAAC,eAAe,IAAO,gBAAgB,EAAE,gBAAgB,YAAG,aAAa,GAAmB,GAC3E,EACnB,KAAC,eAAe,KAAG,IACN,CAChB,CAAC;AACJ,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Errors thrown by `@prnt/dagr-explorer` for data it cannot draw honestly.
|
|
3
|
+
*
|
|
4
|
+
* One class with a `code`, because a caller switches on the code and never on
|
|
5
|
+
* the class: the failures are all "this view is malformed", and they differ
|
|
6
|
+
* only in how. Codes are UPPER_SNAKE and the type is named for the package, as
|
|
7
|
+
* in every sibling.
|
|
8
|
+
*
|
|
9
|
+
* **The offender is a field, not only a phrase in the message.** A host that
|
|
10
|
+
* wants to highlight the bad node, or list the errors of one view, reads `id`
|
|
11
|
+
* and `viewId` and never parses prose. What `id` names depends on the code:
|
|
12
|
+
*
|
|
13
|
+
* - `INVALID_ID`: the empty id itself, so `id` is `''`. `viewId` is the view, or `undefined` when the empty id is a view's.
|
|
14
|
+
* - `DUPLICATE_VIEW_ID`: the view. `viewId` is `undefined`.
|
|
15
|
+
* - `INVALID_LAYOUT_OPTION`: the view. `viewId` is `undefined`.
|
|
16
|
+
* - `DUPLICATE_NODE_ID`, `INVALID_NODE_SIZE`: the node.
|
|
17
|
+
* - `DUPLICATE_EDGE_ID`, `MISSING_EDGE_ENDPOINT`: the edge.
|
|
18
|
+
* - `DUPLICATE_GROUP_ID`, `EMPTY_GROUP`, `MISSING_GROUP_MEMBER`,
|
|
19
|
+
* `GROUP_ENCLOSES_NON_MEMBER`: the group.
|
|
20
|
+
*
|
|
21
|
+
* The message still names every id involved, including the second one a
|
|
22
|
+
* missing endpoint or an enclosed node adds, so a log line is enough to fix it.
|
|
23
|
+
*
|
|
24
|
+
* The prototype is restored explicitly, as every sibling package does, so
|
|
25
|
+
* `instanceof` stays correct when the output is downlevelled below ES2022.
|
|
26
|
+
*/
|
|
27
|
+
/** The `code` of every data error this package throws. */
|
|
28
|
+
export type DagrExplorerErrorCode = 'INVALID_ID' | 'DUPLICATE_VIEW_ID' | 'DUPLICATE_NODE_ID' | 'DUPLICATE_EDGE_ID' | 'DUPLICATE_GROUP_ID' | 'INVALID_NODE_SIZE' | 'INVALID_LAYOUT_OPTION' | 'MISSING_EDGE_ENDPOINT' | 'MISSING_GROUP_MEMBER' | 'EMPTY_GROUP' | 'GROUP_ENCLOSES_NON_MEMBER';
|
|
29
|
+
export declare class ExplorerDataError extends Error {
|
|
30
|
+
readonly code: DagrExplorerErrorCode;
|
|
31
|
+
/** The view, node, edge or group the error is about. See the table above. */
|
|
32
|
+
readonly id: string;
|
|
33
|
+
/** The view it was found in. `undefined` when the error is about a view. */
|
|
34
|
+
readonly viewId: string | undefined;
|
|
35
|
+
constructor(code: DagrExplorerErrorCode, message: string, id: string, viewId?: string);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The `code` of every composition error: a part used where it cannot work.
|
|
39
|
+
*
|
|
40
|
+
* - `OUTSIDE_EXPLORER`: a part, or `useExplorer()`, rendered outside an
|
|
41
|
+
* `ExplorerRoot`. The message names the part.
|
|
42
|
+
* - `SECOND_VIEWPORT`: a second `ExplorerViewport` in one root.
|
|
43
|
+
*/
|
|
44
|
+
export type ExplorerContextErrorCode = 'OUTSIDE_EXPLORER' | 'SECOND_VIEWPORT';
|
|
45
|
+
/**
|
|
46
|
+
* A mistake in how the parts are put together, as opposed to the data. A
|
|
47
|
+
* separate class from {@link ExplorerDataError}, because a host that shows
|
|
48
|
+
* data errors to its users should never show these: they are the host's own
|
|
49
|
+
* bug, found the first time the page renders.
|
|
50
|
+
*/
|
|
51
|
+
export declare class ExplorerContextError extends Error {
|
|
52
|
+
readonly code: ExplorerContextErrorCode;
|
|
53
|
+
constructor(code: ExplorerContextErrorCode, message: string);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,0DAA0D;AAC1D,MAAM,MAAM,qBAAqB,GAC7B,YAAY,GACZ,mBAAmB,GACnB,mBAAmB,GACnB,mBAAmB,GACnB,oBAAoB,GACpB,mBAAmB,GACnB,uBAAuB,GACvB,uBAAuB,GACvB,sBAAsB,GACtB,aAAa,GACb,2BAA2B,CAAC;AAEhC,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IAErC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;gBAExB,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAQtF;AAED;;;;;;GAMG;AACH,MAAM,MAAM,wBAAwB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAE9E;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;gBAE5B,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,MAAM;CAM5D"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Errors thrown by `@prnt/dagr-explorer` for data it cannot draw honestly.
|
|
3
|
+
*
|
|
4
|
+
* One class with a `code`, because a caller switches on the code and never on
|
|
5
|
+
* the class: the failures are all "this view is malformed", and they differ
|
|
6
|
+
* only in how. Codes are UPPER_SNAKE and the type is named for the package, as
|
|
7
|
+
* in every sibling.
|
|
8
|
+
*
|
|
9
|
+
* **The offender is a field, not only a phrase in the message.** A host that
|
|
10
|
+
* wants to highlight the bad node, or list the errors of one view, reads `id`
|
|
11
|
+
* and `viewId` and never parses prose. What `id` names depends on the code:
|
|
12
|
+
*
|
|
13
|
+
* - `INVALID_ID`: the empty id itself, so `id` is `''`. `viewId` is the view, or `undefined` when the empty id is a view's.
|
|
14
|
+
* - `DUPLICATE_VIEW_ID`: the view. `viewId` is `undefined`.
|
|
15
|
+
* - `INVALID_LAYOUT_OPTION`: the view. `viewId` is `undefined`.
|
|
16
|
+
* - `DUPLICATE_NODE_ID`, `INVALID_NODE_SIZE`: the node.
|
|
17
|
+
* - `DUPLICATE_EDGE_ID`, `MISSING_EDGE_ENDPOINT`: the edge.
|
|
18
|
+
* - `DUPLICATE_GROUP_ID`, `EMPTY_GROUP`, `MISSING_GROUP_MEMBER`,
|
|
19
|
+
* `GROUP_ENCLOSES_NON_MEMBER`: the group.
|
|
20
|
+
*
|
|
21
|
+
* The message still names every id involved, including the second one a
|
|
22
|
+
* missing endpoint or an enclosed node adds, so a log line is enough to fix it.
|
|
23
|
+
*
|
|
24
|
+
* The prototype is restored explicitly, as every sibling package does, so
|
|
25
|
+
* `instanceof` stays correct when the output is downlevelled below ES2022.
|
|
26
|
+
*/
|
|
27
|
+
export class ExplorerDataError extends Error {
|
|
28
|
+
code;
|
|
29
|
+
/** The view, node, edge or group the error is about. See the table above. */
|
|
30
|
+
id;
|
|
31
|
+
/** The view it was found in. `undefined` when the error is about a view. */
|
|
32
|
+
viewId;
|
|
33
|
+
constructor(code, message, id, viewId) {
|
|
34
|
+
super(message);
|
|
35
|
+
this.name = 'ExplorerDataError';
|
|
36
|
+
this.code = code;
|
|
37
|
+
this.id = id;
|
|
38
|
+
this.viewId = viewId;
|
|
39
|
+
Object.setPrototypeOf(this, ExplorerDataError.prototype);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A mistake in how the parts are put together, as opposed to the data. A
|
|
44
|
+
* separate class from {@link ExplorerDataError}, because a host that shows
|
|
45
|
+
* data errors to its users should never show these: they are the host's own
|
|
46
|
+
* bug, found the first time the page renders.
|
|
47
|
+
*/
|
|
48
|
+
export class ExplorerContextError extends Error {
|
|
49
|
+
code;
|
|
50
|
+
constructor(code, message) {
|
|
51
|
+
super(message);
|
|
52
|
+
this.name = 'ExplorerContextError';
|
|
53
|
+
this.code = code;
|
|
54
|
+
Object.setPrototypeOf(this, ExplorerContextError.prototype);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAgBH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,IAAI,CAAwB;IAErC,6EAA6E;IACpE,EAAE,CAAS;IAEpB,4EAA4E;IACnE,MAAM,CAAqB;IAEpC,YAAY,IAA2B,EAAE,OAAe,EAAE,EAAU,EAAE,MAAe;QACnF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;CACF;AAWD;;;;;GAKG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,IAAI,CAA2B;IAExC,YAAY,IAA8B,EAAE,OAAe;QACzD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAC9D,CAAC;CACF"}
|