libpetri 2.0.0 → 2.3.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/dist/{chunk-4L6JVKH4.js → chunk-B2CV5M3L.js} +64 -2
- package/dist/chunk-B2CV5M3L.js.map +1 -0
- package/dist/chunk-RNWTYK5B.js +419 -0
- package/dist/chunk-RNWTYK5B.js.map +1 -0
- package/dist/debug/index.d.ts +2 -2
- package/dist/debug/index.js +1 -1
- package/dist/doclet/index.d.ts +1 -1
- package/dist/doclet/index.js +2 -2
- package/dist/doclet/resources/petrinet-diagrams.css +263 -0
- package/dist/doclet/resources/petrinet-diagrams.js +32 -6
- package/dist/dot-exporter-WJMCJEFK.js +8 -0
- package/dist/{event-store-2zkXeQkd.d.ts → event-store-I3QiQABh.d.ts} +1 -1
- package/dist/export/index.d.ts +3 -3
- package/dist/export/index.js +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -1
- package/dist/{petri-net-BDrj4XZE.d.ts → petri-net-CKZYPOsL.d.ts} +30 -0
- package/dist/render-QK57X4TP.js +73 -0
- package/dist/render-QK57X4TP.js.map +1 -0
- package/dist/verification/index.d.ts +2 -2
- package/dist/viewer/index.d.ts +68 -2
- package/dist/viewer/index.js +582 -75
- package/dist/viewer/index.js.map +1 -1
- package/dist/viewer/layout/index.d.ts +200 -0
- package/dist/viewer/layout/index.js +15 -0
- package/dist/viewer/layout/index.js.map +1 -0
- package/dist/viewer/viewer-static.iife.js +4 -2
- package/dist/viewer/viewer.css +263 -0
- package/dist/viewer/viewer.iife.js +32 -6
- package/package.json +12 -1
- package/dist/chunk-4L6JVKH4.js.map +0 -1
- package/dist/dot-exporter-PMHOQHZ3.js +0 -8
- package/dist/render-P6GROU7J.js +0 -16
- package/dist/render-P6GROU7J.js.map +0 -1
- /package/dist/{dot-exporter-PMHOQHZ3.js.map → dot-exporter-WJMCJEFK.js.map} +0 -0
|
@@ -1360,8 +1360,28 @@ declare class PetriNetBuilder {
|
|
|
1360
1360
|
* channel name is unknown on the interface, or when caller- and
|
|
1361
1361
|
* instance-side transition timings conflict (per [MOD-021]).
|
|
1362
1362
|
*/
|
|
1363
|
+
compose(instance: Instance<unknown>): this;
|
|
1363
1364
|
compose(instance: Instance<unknown>, portMappings: ReadonlyMap<string, Place<unknown>> | Record<string, Place<unknown>>): this;
|
|
1364
1365
|
compose(instance: Instance<unknown>, bind: (b: ComposeBindings) => void): this;
|
|
1366
|
+
/**
|
|
1367
|
+
* Identity-default auto-compose per **MOD-024**.
|
|
1368
|
+
*
|
|
1369
|
+
* Each declared interface port auto-binds to its own `port.place` — the
|
|
1370
|
+
* Place the SubnetDef builder declared via `.inputPort(name, hostPlace)`
|
|
1371
|
+
* (or `outputPort` / `inoutPort`). If the host builder already declares
|
|
1372
|
+
* the equal place, the two merge; if not, the place arrives implicitly
|
|
1373
|
+
* via the rewritten transitions' arcs (same flow as explicit `bindPort`).
|
|
1374
|
+
*
|
|
1375
|
+
* If the subnet declares no interface ports at all, body places are
|
|
1376
|
+
* checked against this builder's place set **by name** (matching the
|
|
1377
|
+
* existing TS Place equality semantics; see [CORE-002] note in
|
|
1378
|
+
* `spec/11-modular-composition.md` MOD-024). Body places that don't match
|
|
1379
|
+
* stay private under their prefixed names per [MOD-010].
|
|
1380
|
+
*
|
|
1381
|
+
* Channels are NOT auto-bound — transition identity is too delicate for
|
|
1382
|
+
* inference. If the subnet declares any channel, this overload throws.
|
|
1383
|
+
*/
|
|
1384
|
+
private composeAuto;
|
|
1365
1385
|
/**
|
|
1366
1386
|
* @internal Shared compose implementation: validates port and channel
|
|
1367
1387
|
* bindings, builds the place-substitution map, walks every renamed-body
|
|
@@ -1396,6 +1416,16 @@ declare class PetriNetBuilder {
|
|
|
1396
1416
|
* channel-handle map — but the prefixed names remain stable.
|
|
1397
1417
|
*/
|
|
1398
1418
|
private composeInternal;
|
|
1419
|
+
/**
|
|
1420
|
+
* Shared post-mergeMap pipeline: rewrites renamed-body transitions
|
|
1421
|
+
* through `mergeMap`, applies channel merges per **MOD-021**, and adds
|
|
1422
|
+
* the surviving transitions to the builder.
|
|
1423
|
+
*
|
|
1424
|
+
* Used by both the explicit-binding path (`composeInternal`) and the
|
|
1425
|
+
* auto-compose path (`composeAuto` per **MOD-024**). The two paths differ
|
|
1426
|
+
* only in how the (renamed Place name → host Place) `mergeMap` is built.
|
|
1427
|
+
*/
|
|
1428
|
+
private applyComposition;
|
|
1399
1429
|
/**
|
|
1400
1430
|
* Registers one or more {@link FusionSet} declarations on this builder, per
|
|
1401
1431
|
* **MOD-060** (fusion set declaration) and **MOD-061** (fusion resolution
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
elkLayout,
|
|
3
|
+
foldOrphans,
|
|
4
|
+
parseLibpetriDot,
|
|
5
|
+
replicateShared,
|
|
6
|
+
writeBack
|
|
7
|
+
} from "./chunk-RNWTYK5B.js";
|
|
8
|
+
|
|
9
|
+
// src/viewer/render.ts
|
|
10
|
+
import { instance as vizInstance } from "@viz-js/viz";
|
|
11
|
+
var vizPromise = null;
|
|
12
|
+
function getViz() {
|
|
13
|
+
if (!vizPromise) vizPromise = vizInstance();
|
|
14
|
+
return vizPromise;
|
|
15
|
+
}
|
|
16
|
+
async function renderDotToSvg(dotSource) {
|
|
17
|
+
const viz = await getViz();
|
|
18
|
+
return viz.renderSVGElement(dotSource, { engine: "dot" });
|
|
19
|
+
}
|
|
20
|
+
function fnv1a(input) {
|
|
21
|
+
let h = 2166136261;
|
|
22
|
+
for (let i = 0; i < input.length; i++) {
|
|
23
|
+
h ^= input.charCodeAt(i);
|
|
24
|
+
h = Math.imul(h, 16777619);
|
|
25
|
+
}
|
|
26
|
+
return (h >>> 0).toString(16);
|
|
27
|
+
}
|
|
28
|
+
var PINNED_DOT_CACHE_CAP = 16;
|
|
29
|
+
var pinnedDotCache = /* @__PURE__ */ new Map();
|
|
30
|
+
function getCachedPinnedDot(key) {
|
|
31
|
+
const hit = pinnedDotCache.get(key);
|
|
32
|
+
if (hit !== void 0) {
|
|
33
|
+
pinnedDotCache.delete(key);
|
|
34
|
+
pinnedDotCache.set(key, hit);
|
|
35
|
+
}
|
|
36
|
+
return hit;
|
|
37
|
+
}
|
|
38
|
+
function setCachedPinnedDot(key, value) {
|
|
39
|
+
pinnedDotCache.set(key, value);
|
|
40
|
+
while (pinnedDotCache.size > PINNED_DOT_CACHE_CAP) {
|
|
41
|
+
const oldest = pinnedDotCache.keys().next().value;
|
|
42
|
+
if (oldest === void 0) break;
|
|
43
|
+
pinnedDotCache.delete(oldest);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function _clearElkLayoutCache() {
|
|
47
|
+
pinnedDotCache.clear();
|
|
48
|
+
}
|
|
49
|
+
async function renderDotToSvgWithElkLayout(dotSource) {
|
|
50
|
+
const key = fnv1a(dotSource);
|
|
51
|
+
let pinnedDot = getCachedPinnedDot(key);
|
|
52
|
+
if (pinnedDot === void 0) {
|
|
53
|
+
const graph = replicateShared(
|
|
54
|
+
foldOrphans(parseLibpetriDot(dotSource), 0.7),
|
|
55
|
+
{ max: Infinity }
|
|
56
|
+
);
|
|
57
|
+
const layout = await elkLayout(graph);
|
|
58
|
+
pinnedDot = writeBack(graph, layout);
|
|
59
|
+
setCachedPinnedDot(key, pinnedDot);
|
|
60
|
+
}
|
|
61
|
+
const viz = await getViz();
|
|
62
|
+
return viz.renderSVGElement(pinnedDot, {
|
|
63
|
+
engine: "nop",
|
|
64
|
+
yInvert: true
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
_clearElkLayoutCache,
|
|
69
|
+
getViz,
|
|
70
|
+
renderDotToSvg,
|
|
71
|
+
renderDotToSvgWithElkLayout
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=render-QK57X4TP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/viewer/render.ts"],"sourcesContent":["/**\n * DOT → SVG rendering for the canonical libpetri viewer.\n *\n * Two render paths:\n *\n * renderDotToSvg(dot) — plain Graphviz `dot` engine.\n * renderDotToSvgWithElkLayout(dot) — C0 pipeline: parse → fold →\n * replicate → ELK → writeBack →\n * Graphviz `neato` with `nop=1`\n * (pin mode). Cached by DOT hash.\n *\n * The ELK path is the default for {@link mount}; the plain-Graphviz path\n * remains as a fallback for callers that want stock layout (or for\n * environments where elkjs isn't installed).\n *\n * @module viewer/render\n */\n\nimport { instance as vizInstance } from '@viz-js/viz';\nimport {\n foldOrphans,\n parseLibpetriDot,\n replicateShared,\n} from './layout/preprocess.js';\nimport { elkLayout, writeBack } from './layout/elk-place.js';\n\ntype Viz = Awaited<ReturnType<typeof vizInstance>>;\n\nlet vizPromise: Promise<Viz> | null = null;\n\n/** Memoize the viz.js instance so the wasm loads only once per page. */\nexport function getViz(): Promise<Viz> {\n if (!vizPromise) vizPromise = vizInstance();\n return vizPromise;\n}\n\n/**\n * Render a DOT source string to an SVGSVGElement using the plain `dot`\n * engine. Deterministic across runs; libpetri exporters emit byte-stable\n * DOT per spec EXP-014 so the same DOT yields the same SVG.\n */\nexport async function renderDotToSvg(dotSource: string): Promise<SVGSVGElement> {\n const viz = await getViz();\n return viz.renderSVGElement(dotSource, { engine: 'dot' });\n}\n\n// ---- C0 / ELK pin-mode cache ---------------------------------------------\n\n/** FNV-1a 32-bit hash. Fast enough that a SHA isn't worth the import. */\nfunction fnv1a(input: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(16);\n}\n\nconst PINNED_DOT_CACHE_CAP = 16;\nconst pinnedDotCache = new Map<string, string>();\n\nfunction getCachedPinnedDot(key: string): string | undefined {\n const hit = pinnedDotCache.get(key);\n if (hit !== undefined) {\n // LRU touch: re-insert moves to most-recent position in Map ordering.\n pinnedDotCache.delete(key);\n pinnedDotCache.set(key, hit);\n }\n return hit;\n}\n\nfunction setCachedPinnedDot(key: string, value: string): void {\n pinnedDotCache.set(key, value);\n while (pinnedDotCache.size > PINNED_DOT_CACHE_CAP) {\n const oldest = pinnedDotCache.keys().next().value;\n if (oldest === undefined) break;\n pinnedDotCache.delete(oldest);\n }\n}\n\n/** Test helper — clears the pinned-DOT LRU cache between mounts. */\nexport function _clearElkLayoutCache(): void {\n pinnedDotCache.clear();\n}\n\n/**\n * Run the C0 layout pipeline against a libpetri DOT source and return the\n * rendered SVG. The expensive steps (preprocess + ELK layout + DOT rewrite)\n * are cached keyed on the input DOT's hash, so re-mounts on the same net\n * structure skip everything except the Graphviz pin-mode draw.\n *\n * Per-tick marking updates do NOT call this — they toggle classes on the\n * already-mounted SVG. ELK only runs when the net structure changes.\n */\nexport async function renderDotToSvgWithElkLayout(\n dotSource: string,\n): Promise<SVGSVGElement> {\n const key = fnv1a(dotSource);\n let pinnedDot = getCachedPinnedDot(key);\n if (pinnedDot === undefined) {\n const graph = replicateShared(\n foldOrphans(parseLibpetriDot(dotSource), 0.7),\n { max: Infinity },\n );\n const layout = await elkLayout(graph);\n pinnedDot = writeBack(graph, layout);\n setCachedPinnedDot(key, pinnedDot);\n }\n const viz = await getViz();\n return viz.renderSVGElement(pinnedDot, {\n engine: 'nop',\n yInvert: true,\n });\n}\n"],"mappings":";;;;;;;;;AAkBA,SAAS,YAAY,mBAAmB;AAUxC,IAAI,aAAkC;AAG/B,SAAS,SAAuB;AACrC,MAAI,CAAC,WAAY,cAAa,YAAY;AAC1C,SAAO;AACT;AAOA,eAAsB,eAAe,WAA2C;AAC9E,QAAM,MAAM,MAAM,OAAO;AACzB,SAAO,IAAI,iBAAiB,WAAW,EAAE,QAAQ,MAAM,CAAC;AAC1D;AAKA,SAAS,MAAM,OAAuB;AACpC,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,SAAK,MAAM,WAAW,CAAC;AACvB,QAAI,KAAK,KAAK,GAAG,QAAU;AAAA,EAC7B;AACA,UAAQ,MAAM,GAAG,SAAS,EAAE;AAC9B;AAEA,IAAM,uBAAuB;AAC7B,IAAM,iBAAiB,oBAAI,IAAoB;AAE/C,SAAS,mBAAmB,KAAiC;AAC3D,QAAM,MAAM,eAAe,IAAI,GAAG;AAClC,MAAI,QAAQ,QAAW;AAErB,mBAAe,OAAO,GAAG;AACzB,mBAAe,IAAI,KAAK,GAAG;AAAA,EAC7B;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,KAAa,OAAqB;AAC5D,iBAAe,IAAI,KAAK,KAAK;AAC7B,SAAO,eAAe,OAAO,sBAAsB;AACjD,UAAM,SAAS,eAAe,KAAK,EAAE,KAAK,EAAE;AAC5C,QAAI,WAAW,OAAW;AAC1B,mBAAe,OAAO,MAAM;AAAA,EAC9B;AACF;AAGO,SAAS,uBAA6B;AAC3C,iBAAe,MAAM;AACvB;AAWA,eAAsB,4BACpB,WACwB;AACxB,QAAM,MAAM,MAAM,SAAS;AAC3B,MAAI,YAAY,mBAAmB,GAAG;AACtC,MAAI,cAAc,QAAW;AAC3B,UAAM,QAAQ;AAAA,MACZ,YAAY,iBAAiB,SAAS,GAAG,GAAG;AAAA,MAC5C,EAAE,KAAK,SAAS;AAAA,IAClB;AACA,UAAM,SAAS,MAAM,UAAU,KAAK;AACpC,gBAAY,UAAU,OAAO,MAAM;AACnC,uBAAmB,KAAK,SAAS;AAAA,EACnC;AACA,QAAM,MAAM,MAAM,OAAO;AACzB,SAAO,IAAI,iBAAiB,WAAW;AAAA,IACrC,QAAQ;AAAA,IACR,SAAS;AAAA,EACX,CAAC;AACH;","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as Transition, a as Place, P as PetriNet, E as EnvironmentPlace, aG as MarkingState, aH as PInvariant, aI as MarkingStateBuilder, aJ as SmtProperty, aK as SmtVerificationResult } from '../petri-net-
|
|
2
|
-
export { aL as DeadlockFree, aM as MutualExclusion, aN as PlaceBound, aO as Proven, aP as SmtStatistics, aQ as TokenSupplier, aR as Unknown, aS as Unreachable, aT as Verdict, X as VerificationHarness, Y as VerificationResult, aU as Violated, aV as deadlockFree, aW as isProven, aX as isViolated, aY as mutualExclusion, aZ as pInvariant, a_ as pInvariantToString, a$ as placeBound, b0 as propertyDescription, b1 as unreachable } from '../petri-net-
|
|
1
|
+
import { b as Transition, a as Place, P as PetriNet, E as EnvironmentPlace, aG as MarkingState, aH as PInvariant, aI as MarkingStateBuilder, aJ as SmtProperty, aK as SmtVerificationResult } from '../petri-net-CKZYPOsL.js';
|
|
2
|
+
export { aL as DeadlockFree, aM as MutualExclusion, aN as PlaceBound, aO as Proven, aP as SmtStatistics, aQ as TokenSupplier, aR as Unknown, aS as Unreachable, aT as Verdict, X as VerificationHarness, Y as VerificationResult, aU as Violated, aV as deadlockFree, aW as isProven, aX as isViolated, aY as mutualExclusion, aZ as pInvariant, a_ as pInvariantToString, a$ as placeBound, b0 as propertyDescription, b1 as unreachable } from '../petri-net-CKZYPOsL.js';
|
|
3
3
|
import { Expr, init, Bool, FuncDecl } from 'z3-solver';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/viewer/index.d.ts
CHANGED
|
@@ -82,6 +82,17 @@ declare function discoverClusters(svg: SVGSVGElement): Map<string, ClusterDescri
|
|
|
82
82
|
*/
|
|
83
83
|
declare function colorForPrefix(prefix: string): string;
|
|
84
84
|
|
|
85
|
+
interface VisibilityState {
|
|
86
|
+
/** Cluster short names currently visible. */
|
|
87
|
+
readonly visibleClusters: ReadonlySet<string>;
|
|
88
|
+
/**
|
|
89
|
+
* When false, hide every replica/shared place (`g.node.petri-replica`)
|
|
90
|
+
* regardless of which cluster it belongs to. The corresponding sidebar
|
|
91
|
+
* checkbox is labelled "Shared places".
|
|
92
|
+
*/
|
|
93
|
+
readonly includeSharedPlaces: boolean;
|
|
94
|
+
}
|
|
95
|
+
|
|
85
96
|
/**
|
|
86
97
|
* CSS custom properties exposed by the canonical viewer stylesheet.
|
|
87
98
|
*
|
|
@@ -96,7 +107,7 @@ declare function colorForPrefix(prefix: string): string;
|
|
|
96
107
|
* @module viewer/styles
|
|
97
108
|
*/
|
|
98
109
|
/** CSS custom property names that the canonical stylesheet honours. */
|
|
99
|
-
declare const VIEWER_CSS_VARIABLES: readonly ["--lpv-bg", "--lpv-header-bg", "--lpv-border", "--lpv-text", "--lpv-muted", "--lpv-cluster-bg", "--lpv-cluster-bg-collapsed", "--lpv-cluster-stroke-width", "--lpv-cluster-stroke-dash", "--lpv-cluster-fill-tint", "--lpv-dim-opacity", "--lpv-active-filter-outline", "--lpv-legend-bg", "--lpv-chip-bg", "--lpv-chip-active-bg"];
|
|
110
|
+
declare const VIEWER_CSS_VARIABLES: readonly ["--lpv-bg", "--lpv-header-bg", "--lpv-border", "--lpv-text", "--lpv-muted", "--lpv-cluster-bg", "--lpv-cluster-bg-collapsed", "--lpv-cluster-stroke-width", "--lpv-cluster-stroke-dash", "--lpv-cluster-fill-tint", "--lpv-dim-opacity", "--lpv-active-filter-outline", "--lpv-legend-bg", "--lpv-chip-bg", "--lpv-chip-active-bg", "--lpv-sidebar-bg", "--lpv-sidebar-border", "--lpv-sidebar-text", "--lpv-sidebar-muted", "--lpv-sidebar-chip-bg", "--lpv-sidebar-chip-hover-bg", "--lpv-sidebar-chip-off-opacity", "--lpv-shared-glyph-color", "--lpv-replica-fill", "--lpv-replica-stroke", "--lpv-highlight-stroke", "--lpv-highlight-glow", "--lpv-neighbor-stroke", "--lpv-faded-node-opacity", "--lpv-faded-edge-opacity", "--lpv-faded-cluster-opacity"];
|
|
100
111
|
|
|
101
112
|
/**
|
|
102
113
|
* Canonical libpetri Petri-net diagram viewer.
|
|
@@ -124,6 +135,16 @@ declare const VIEWER_CSS_VARIABLES: readonly ["--lpv-bg", "--lpv-header-bg", "--
|
|
|
124
135
|
* @module viewer
|
|
125
136
|
*/
|
|
126
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Subnet (cluster) visibility mode.
|
|
140
|
+
*
|
|
141
|
+
* - `'show'` — render the DOT as-is with `subgraph cluster_*` groupings
|
|
142
|
+
* visible (the default; the post-subnets layout).
|
|
143
|
+
* - `'hide'` — render a flattened variant that drops cluster wrappers
|
|
144
|
+
* and the `ltail`/`lhead` cluster references on cross-cluster edges.
|
|
145
|
+
* Same nodes and edges, no visual grouping.
|
|
146
|
+
*/
|
|
147
|
+
type SubnetVisibility = 'show' | 'hide';
|
|
127
148
|
/** Handle returned by {@link mount}. */
|
|
128
149
|
interface ViewerHandle {
|
|
129
150
|
/** The rendered root `<svg>` element. */
|
|
@@ -136,6 +157,22 @@ interface ViewerHandle {
|
|
|
136
157
|
readonly collapsedPrefixes: ReadonlySet<string>;
|
|
137
158
|
/** Currently active "show only <prefix>" filter, or null. */
|
|
138
159
|
readonly activeFilter: string | null;
|
|
160
|
+
/** Current subnet visibility mode. */
|
|
161
|
+
readonly subnets: SubnetVisibility;
|
|
162
|
+
/**
|
|
163
|
+
* Switch between the clustered (`'show'`) and flat (`'hide'`) views.
|
|
164
|
+
* Triggers an internal re-mount via the canonical {@link mount} path —
|
|
165
|
+
* the SVG is regenerated because Graphviz lays out cluster boundaries
|
|
166
|
+
* during layout. Returns the new handle; the old one is disposed.
|
|
167
|
+
*
|
|
168
|
+
* After re-mount, the host container dispatches a bubbling
|
|
169
|
+
* `libpetri-viewer:remount` CustomEvent whose `detail.handle` is the
|
|
170
|
+
* fresh handle. Consumers that cache the handle (e.g. the debug-ui)
|
|
171
|
+
* should listen on the container and update their reference.
|
|
172
|
+
*/
|
|
173
|
+
setSubnets(mode: SubnetVisibility): Promise<ViewerHandle>;
|
|
174
|
+
/** Flip {@link subnets} to the other mode and re-mount. See {@link setSubnets}. */
|
|
175
|
+
toggleSubnets(): Promise<ViewerHandle>;
|
|
139
176
|
/** Collapse a single cluster by prefix. No-op if unknown. */
|
|
140
177
|
collapse(prefix: string): void;
|
|
141
178
|
/** Expand a single cluster by prefix. No-op if unknown. */
|
|
@@ -152,6 +189,18 @@ interface ViewerHandle {
|
|
|
152
189
|
fit(): void;
|
|
153
190
|
/** Reports whether `graphId` is inside a currently-collapsed cluster. */
|
|
154
191
|
isInsideCollapsedCluster(graphId: string): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Highlight a node and every DOM copy of the same logical place; walk
|
|
194
|
+
* junctions to surface real neighbors. Pass `null` to clear. C0-only.
|
|
195
|
+
*/
|
|
196
|
+
highlight(nodeId: string | null): void;
|
|
197
|
+
/** The node id currently highlighted, or `null`. */
|
|
198
|
+
readonly highlightedNodeId: string | null;
|
|
199
|
+
/**
|
|
200
|
+
* Set the cluster-visibility state: which clusters render, and whether
|
|
201
|
+
* directed-reachable orphans render. C0-only.
|
|
202
|
+
*/
|
|
203
|
+
setVisibility(state: VisibilityState): void;
|
|
155
204
|
/** Tear down: dispose panzoom and detach listeners. */
|
|
156
205
|
dispose(): void;
|
|
157
206
|
}
|
|
@@ -172,6 +221,23 @@ interface MountOptions {
|
|
|
172
221
|
readonly onClusterFilter?: (prefix: string | null) => void;
|
|
173
222
|
/** When true, append a legend sidebar + filter chip strip inside `container`. */
|
|
174
223
|
readonly chrome?: boolean;
|
|
224
|
+
/**
|
|
225
|
+
* Layout strategy. `'elk'` (default) runs the C0 pipeline — parse → fold
|
|
226
|
+
* → replicate → ELK → Graphviz `neato` pin mode — and tags replica
|
|
227
|
+
* nodes for the click-all-copies + ⇄ overlay. `'graphviz'` runs the
|
|
228
|
+
* plain Graphviz `dot` engine and skips replica tagging. The result is
|
|
229
|
+
* cached on the DOT hash; re-mounts on identical DOT skip the pipeline.
|
|
230
|
+
*/
|
|
231
|
+
readonly layout?: 'elk' | 'graphviz';
|
|
232
|
+
/**
|
|
233
|
+
* Initial subnet visibility mode. Defaults to `'show'` (clustered view).
|
|
234
|
+
* Pass `'hide'` to mount with the flat view from the start. The chrome
|
|
235
|
+
* button toggles between the two at runtime; see {@link ViewerHandle.setSubnets}.
|
|
236
|
+
*
|
|
237
|
+
* If `previousHandle` is supplied and `subnets` is omitted, the previous
|
|
238
|
+
* handle's mode is inherited so live re-renders preserve the user's choice.
|
|
239
|
+
*/
|
|
240
|
+
readonly subnets?: SubnetVisibility;
|
|
175
241
|
}
|
|
176
242
|
/**
|
|
177
243
|
* Render a DOT source, mount the resulting SVG into `container`, wire pan/zoom,
|
|
@@ -193,4 +259,4 @@ interface MountOptions {
|
|
|
193
259
|
*/
|
|
194
260
|
declare function mount(dotSource: string | null, container: HTMLElement, opts?: MountOptions): Promise<ViewerHandle>;
|
|
195
261
|
|
|
196
|
-
export { type ClusterDescriptor, DEFAULT_PANZOOM_OPTS, type MountOptions, type PanzoomInstance, type PanzoomOptions, VIEWER_CSS_VARIABLES, type ViewerHandle, colorForPrefix, discoverClusters, mount };
|
|
262
|
+
export { type ClusterDescriptor, DEFAULT_PANZOOM_OPTS, type MountOptions, type PanzoomInstance, type PanzoomOptions, type SubnetVisibility, VIEWER_CSS_VARIABLES, type ViewerHandle, colorForPrefix, discoverClusters, mount };
|