@aiready/visualizer 0.6.6 → 0.6.8

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.
@@ -21614,6 +21614,7 @@ var string$1 = (params) => {
21614
21614
  };
21615
21615
  var integer = /^-?\d+$/;
21616
21616
  var number$1 = /^-?\d+(?:\.\d+)?$/;
21617
+ var boolean$1 = /^(?:true|false)$/i;
21617
21618
  var lowercase = /^[^A-Z]*$/;
21618
21619
  var uppercase = /^[^a-z]*$/;
21619
21620
  //#endregion
@@ -22388,6 +22389,24 @@ var $ZodNumberFormat = /* @__PURE__ */ $constructor("$ZodNumberFormat", (inst, d
22388
22389
  $ZodCheckNumberFormat.init(inst, def);
22389
22390
  $ZodNumber.init(inst, def);
22390
22391
  });
22392
+ var $ZodBoolean = /* @__PURE__ */ $constructor("$ZodBoolean", (inst, def) => {
22393
+ $ZodType.init(inst, def);
22394
+ inst._zod.pattern = boolean$1;
22395
+ inst._zod.parse = (payload, _ctx) => {
22396
+ if (def.coerce) try {
22397
+ payload.value = Boolean(payload.value);
22398
+ } catch (_) {}
22399
+ const input = payload.value;
22400
+ if (typeof input === "boolean") return payload;
22401
+ payload.issues.push({
22402
+ expected: "boolean",
22403
+ code: "invalid_type",
22404
+ input,
22405
+ inst
22406
+ });
22407
+ return payload;
22408
+ };
22409
+ });
22391
22410
  var $ZodAny = /* @__PURE__ */ $constructor("$ZodAny", (inst, def) => {
22392
22411
  $ZodType.init(inst, def);
22393
22412
  inst._zod.parse = (payload) => payload;
@@ -22795,6 +22814,97 @@ function handleIntersectionResults(result, left, right) {
22795
22814
  result.value = merged.data;
22796
22815
  return result;
22797
22816
  }
22817
+ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
22818
+ $ZodType.init(inst, def);
22819
+ inst._zod.parse = (payload, ctx) => {
22820
+ const input = payload.value;
22821
+ if (!isPlainObject(input)) {
22822
+ payload.issues.push({
22823
+ expected: "record",
22824
+ code: "invalid_type",
22825
+ input,
22826
+ inst
22827
+ });
22828
+ return payload;
22829
+ }
22830
+ const proms = [];
22831
+ const values = def.keyType._zod.values;
22832
+ if (values) {
22833
+ payload.value = {};
22834
+ const recordKeys = /* @__PURE__ */ new Set();
22835
+ for (const key of values) if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
22836
+ recordKeys.add(typeof key === "number" ? key.toString() : key);
22837
+ const result = def.valueType._zod.run({
22838
+ value: input[key],
22839
+ issues: []
22840
+ }, ctx);
22841
+ if (result instanceof Promise) proms.push(result.then((result) => {
22842
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
22843
+ payload.value[key] = result.value;
22844
+ }));
22845
+ else {
22846
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
22847
+ payload.value[key] = result.value;
22848
+ }
22849
+ }
22850
+ let unrecognized;
22851
+ for (const key in input) if (!recordKeys.has(key)) {
22852
+ unrecognized = unrecognized ?? [];
22853
+ unrecognized.push(key);
22854
+ }
22855
+ if (unrecognized && unrecognized.length > 0) payload.issues.push({
22856
+ code: "unrecognized_keys",
22857
+ input,
22858
+ inst,
22859
+ keys: unrecognized
22860
+ });
22861
+ } else {
22862
+ payload.value = {};
22863
+ for (const key of Reflect.ownKeys(input)) {
22864
+ if (key === "__proto__") continue;
22865
+ let keyResult = def.keyType._zod.run({
22866
+ value: key,
22867
+ issues: []
22868
+ }, ctx);
22869
+ if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
22870
+ if (typeof key === "string" && number$1.test(key) && keyResult.issues.length) {
22871
+ const retryResult = def.keyType._zod.run({
22872
+ value: Number(key),
22873
+ issues: []
22874
+ }, ctx);
22875
+ if (retryResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
22876
+ if (retryResult.issues.length === 0) keyResult = retryResult;
22877
+ }
22878
+ if (keyResult.issues.length) {
22879
+ if (def.mode === "loose") payload.value[key] = input[key];
22880
+ else payload.issues.push({
22881
+ code: "invalid_key",
22882
+ origin: "record",
22883
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
22884
+ input: key,
22885
+ path: [key],
22886
+ inst
22887
+ });
22888
+ continue;
22889
+ }
22890
+ const result = def.valueType._zod.run({
22891
+ value: input[key],
22892
+ issues: []
22893
+ }, ctx);
22894
+ if (result instanceof Promise) proms.push(result.then((result) => {
22895
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
22896
+ payload.value[keyResult.value] = result.value;
22897
+ }));
22898
+ else {
22899
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
22900
+ payload.value[keyResult.value] = result.value;
22901
+ }
22902
+ }
22903
+ }
22904
+ if (proms.length) return Promise.all(proms).then(() => payload);
22905
+ return payload;
22906
+ };
22907
+ });
22798
22908
  var $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
22799
22909
  $ZodType.init(inst, def);
22800
22910
  const values = getEnumValues(def.entries);
@@ -23372,6 +23482,13 @@ function _int(Class, params) {
23372
23482
  });
23373
23483
  }
23374
23484
  /* @__NO_SIDE_EFFECTS__ */
23485
+ function _boolean(Class, params) {
23486
+ return new Class({
23487
+ type: "boolean",
23488
+ ...normalizeParams(params)
23489
+ });
23490
+ }
23491
+ /* @__NO_SIDE_EFFECTS__ */
23375
23492
  function _any(Class) {
23376
23493
  return new Class({ type: "any" });
23377
23494
  }
@@ -23918,6 +24035,9 @@ var numberProcessor = (schema, ctx, _json, _params) => {
23918
24035
  }
23919
24036
  if (typeof multipleOf === "number") json.multipleOf = multipleOf;
23920
24037
  };
24038
+ var booleanProcessor = (_schema, _ctx, json, _params) => {
24039
+ json.type = "boolean";
24040
+ };
23921
24041
  var neverProcessor = (_schema, _ctx, json, _params) => {
23922
24042
  json.not = {};
23923
24043
  };
@@ -24012,6 +24132,39 @@ var intersectionProcessor = (schema, ctx, json, params) => {
24012
24132
  const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1;
24013
24133
  json.allOf = [...isSimpleIntersection(a) ? a.allOf : [a], ...isSimpleIntersection(b) ? b.allOf : [b]];
24014
24134
  };
24135
+ var recordProcessor = (schema, ctx, _json, params) => {
24136
+ const json = _json;
24137
+ const def = schema._zod.def;
24138
+ json.type = "object";
24139
+ const keyType = def.keyType;
24140
+ const patterns = keyType._zod.bag?.patterns;
24141
+ if (def.mode === "loose" && patterns && patterns.size > 0) {
24142
+ const valueSchema = process$1(def.valueType, ctx, {
24143
+ ...params,
24144
+ path: [
24145
+ ...params.path,
24146
+ "patternProperties",
24147
+ "*"
24148
+ ]
24149
+ });
24150
+ json.patternProperties = {};
24151
+ for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
24152
+ } else {
24153
+ if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$1(def.keyType, ctx, {
24154
+ ...params,
24155
+ path: [...params.path, "propertyNames"]
24156
+ });
24157
+ json.additionalProperties = process$1(def.valueType, ctx, {
24158
+ ...params,
24159
+ path: [...params.path, "additionalProperties"]
24160
+ });
24161
+ }
24162
+ const keyValues = keyType._zod.values;
24163
+ if (keyValues) {
24164
+ const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
24165
+ if (validKeyValues.length > 0) json.required = validKeyValues;
24166
+ }
24167
+ };
24015
24168
  var nullableProcessor = (schema, ctx, json, params) => {
24016
24169
  const def = schema._zod.def;
24017
24170
  const inner = process$1(def.innerType, ctx, params);
@@ -24394,6 +24547,14 @@ var ZodNumberFormat = /* @__PURE__ */ $constructor("ZodNumberFormat", (inst, def
24394
24547
  function int(params) {
24395
24548
  return /* @__PURE__ */ _int(ZodNumberFormat, params);
24396
24549
  }
24550
+ var ZodBoolean = /* @__PURE__ */ $constructor("ZodBoolean", (inst, def) => {
24551
+ $ZodBoolean.init(inst, def);
24552
+ ZodType.init(inst, def);
24553
+ inst._zod.processJSONSchema = (ctx, json, params) => booleanProcessor(inst, ctx, json, params);
24554
+ });
24555
+ function boolean(params) {
24556
+ return /* @__PURE__ */ _boolean(ZodBoolean, params);
24557
+ }
24397
24558
  var ZodAny = /* @__PURE__ */ $constructor("ZodAny", (inst, def) => {
24398
24559
  $ZodAny.init(inst, def);
24399
24560
  ZodType.init(inst, def);
@@ -24504,6 +24665,21 @@ function intersection(left, right) {
24504
24665
  right
24505
24666
  });
24506
24667
  }
24668
+ var ZodRecord = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
24669
+ $ZodRecord.init(inst, def);
24670
+ ZodType.init(inst, def);
24671
+ inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params);
24672
+ inst.keyType = def.keyType;
24673
+ inst.valueType = def.valueType;
24674
+ });
24675
+ function record(keyType, valueType, params) {
24676
+ return new ZodRecord({
24677
+ type: "record",
24678
+ keyType,
24679
+ valueType,
24680
+ ...normalizeParams(params)
24681
+ });
24682
+ }
24507
24683
  var ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
24508
24684
  $ZodEnum.init(inst, def);
24509
24685
  ZodType.init(inst, def);
@@ -24719,7 +24895,7 @@ function superRefine(fn) {
24719
24895
  return /* @__PURE__ */ _superRefine(fn);
24720
24896
  }
24721
24897
  //#endregion
24722
- //#region ../../core/dist/chunk-Q55AMEFV.mjs
24898
+ //#region ../../core/dist/chunk-CGOS2J6T.mjs
24723
24899
  var Severity = /* @__PURE__ */ ((Severity2) => {
24724
24900
  Severity2["Critical"] = "critical";
24725
24901
  Severity2["Major"] = "major";
@@ -24858,6 +25034,41 @@ object({
24858
25034
  }).catchall(any()))
24859
25035
  }).optional()
24860
25036
  }).catchall(any());
25037
+ object({
25038
+ threshold: number().optional(),
25039
+ include: array$1(string()).optional(),
25040
+ exclude: array$1(string()).optional(),
25041
+ scan: object({
25042
+ include: array$1(string()).optional(),
25043
+ exclude: array$1(string()).optional(),
25044
+ parallel: boolean().optional(),
25045
+ deep: boolean().optional(),
25046
+ tools: array$1(string()).optional()
25047
+ }).optional(),
25048
+ output: object({
25049
+ format: _enum([
25050
+ "json",
25051
+ "console",
25052
+ "html"
25053
+ ]).optional(),
25054
+ path: string().optional(),
25055
+ saveTo: string().optional(),
25056
+ showBreakdown: boolean().optional(),
25057
+ compareBaseline: string().optional()
25058
+ }).optional(),
25059
+ tools: record(string(), any()).optional(),
25060
+ scoring: object({
25061
+ profile: string().optional(),
25062
+ weights: record(string(), number()).optional()
25063
+ }).optional(),
25064
+ visualizer: object({
25065
+ groupingDirs: array$1(string()).optional(),
25066
+ graph: object({
25067
+ maxNodes: number().optional(),
25068
+ maxEdges: number().optional()
25069
+ }).optional()
25070
+ }).optional()
25071
+ }).catchall(any());
24861
25072
  var LeadSource = /* @__PURE__ */ ((LeadSource2) => {
24862
25073
  LeadSource2["ClawMoreHero"] = "clawmore-hero";
24863
25074
  LeadSource2["ClawMoreWaitlist"] = "clawmore-waitlist";
@@ -28216,7 +28427,156 @@ var LinkItem = ({ link, onClick, defaultWidth, showLabel = true, nodes = [] }) =
28216
28427
  })] });
28217
28428
  };
28218
28429
  var LinkItem_default = LinkItem;
28219
- var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, links: initialLinks, width, height, enableZoom = true, enableDrag = true, onNodeClick, onNodeHover, onLinkClick, selectedNodeId, hoveredNodeId, defaultNodeColor = "#69b3a2", defaultNodeSize = 10, defaultLinkColor = "#999", defaultLinkWidth = 1, showNodeLabels = true, showLinkLabels = false, className, manualLayout = false, onManualLayoutChange, packageBounds, layout: externalLayout, onLayoutChange }, ref) => {
28430
+ var DEFAULT_NODE_COLOR = "#64748b";
28431
+ var DEFAULT_NODE_SIZE = 10;
28432
+ var DEFAULT_LINK_COLOR = "#94a3b8";
28433
+ var DEFAULT_LINK_WIDTH = 1;
28434
+ var CIRCULAR_LAYOUT_RADIUS_RATIO = .35;
28435
+ var FIT_VIEW_PADDING = 40;
28436
+ var TRANSITION_DURATION_MS = 300;
28437
+ var PACKAGE_BOUNDARY_FILL = "rgba(148,163,184,0.06)";
28438
+ var PACKAGE_BOUNDARY_STROKE = "#475569";
28439
+ var PACKAGE_BOUNDARY_STROKE_WIDTH = 2;
28440
+ var PACKAGE_BOUNDARY_DASH = "6 6";
28441
+ var PACKAGE_LABEL_FONT_SIZE = 11;
28442
+ var PACKAGE_LABEL_COLOR = "#475569";
28443
+ var PackageBoundaries = ({ packageBounds }) => {
28444
+ if (!packageBounds || Object.keys(packageBounds).length === 0) return null;
28445
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", {
28446
+ className: "package-boundaries",
28447
+ pointerEvents: "none",
28448
+ children: Object.entries(packageBounds).map(([pid, b]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
28449
+ cx: b.x,
28450
+ cy: b.y,
28451
+ r: b.r,
28452
+ fill: PACKAGE_BOUNDARY_FILL,
28453
+ stroke: PACKAGE_BOUNDARY_STROKE,
28454
+ strokeWidth: PACKAGE_BOUNDARY_STROKE_WIDTH,
28455
+ strokeDasharray: PACKAGE_BOUNDARY_DASH,
28456
+ opacity: .9
28457
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
28458
+ x: b.x,
28459
+ y: Math.max(12, b.y - b.r + 14),
28460
+ fill: PACKAGE_LABEL_COLOR,
28461
+ fontSize: PACKAGE_LABEL_FONT_SIZE,
28462
+ textAnchor: "middle",
28463
+ pointerEvents: "none",
28464
+ children: pid.replace(/^pkg:/, "")
28465
+ })] }, pid))
28466
+ });
28467
+ };
28468
+ PackageBoundaries.displayName = "PackageBoundaries";
28469
+ function applyCircularLayout(nodes, width, height) {
28470
+ const centerX = width / 2;
28471
+ const centerY = height / 2;
28472
+ const radius = Math.min(width, height) * CIRCULAR_LAYOUT_RADIUS_RATIO;
28473
+ nodes.forEach((node, i) => {
28474
+ const angle = 2 * Math.PI * i / nodes.length;
28475
+ node.fx = centerX + Math.cos(angle) * radius;
28476
+ node.fy = centerY + Math.sin(angle) * radius;
28477
+ node.x = node.fx;
28478
+ node.y = node.fy;
28479
+ });
28480
+ }
28481
+ function applyHierarchicalLayout(nodes, width, height) {
28482
+ const groups = /* @__PURE__ */ new Map();
28483
+ nodes.forEach((n) => {
28484
+ const key = n.packageGroup || n.group || "root";
28485
+ if (!groups.has(key)) groups.set(key, []);
28486
+ groups.get(key).push(n);
28487
+ });
28488
+ const groupArray = Array.from(groups.entries());
28489
+ const cols = Math.ceil(Math.sqrt(groupArray.length));
28490
+ const groupSpacingX = width * .8 / cols;
28491
+ const groupSpacingY = height * .8 / Math.ceil(groupArray.length / cols);
28492
+ groupArray.forEach(([groupKey, groupNodes], gi) => {
28493
+ const col = gi % cols;
28494
+ const row = Math.floor(gi / cols);
28495
+ const groupX = (col + .5) * groupSpacingX;
28496
+ const groupY = (row + .5) * groupSpacingY;
28497
+ if (groupKey.startsWith("pkg:") || groupKey === groupKey) groupNodes.forEach((n, ni) => {
28498
+ const angle = 2 * Math.PI * ni / groupNodes.length;
28499
+ const r = Math.min(80, 20 + groupNodes.length * 8);
28500
+ n.fx = groupX + Math.cos(angle) * r;
28501
+ n.fy = groupY + Math.sin(angle) * r;
28502
+ n.x = n.fx;
28503
+ n.y = n.fy;
28504
+ });
28505
+ });
28506
+ }
28507
+ function applyInitialForceLayout(nodes, width, height) {
28508
+ nodes.forEach((node) => {
28509
+ if (node.fx === void 0 || node.fx === null) {
28510
+ node.x = Math.random() * width;
28511
+ node.y = Math.random() * height;
28512
+ }
28513
+ });
28514
+ }
28515
+ function useGraphZoom(svgRef, gRef, enableZoom, setTransform, transformRef) {
28516
+ (0, import_react.useEffect)(() => {
28517
+ if (!enableZoom || !svgRef.current || !gRef.current) return;
28518
+ const svg = select_default$1(svgRef.current);
28519
+ const g = select_default$1(gRef.current);
28520
+ const zoom3 = zoom_default().scaleExtent([.1, 10]).on("zoom", (event) => {
28521
+ g.attr("transform", event.transform);
28522
+ transformRef.current = event.transform;
28523
+ setTransform(event.transform);
28524
+ });
28525
+ svg.call(zoom3);
28526
+ return () => {
28527
+ svg.on(".zoom", null);
28528
+ };
28529
+ }, [
28530
+ enableZoom,
28531
+ svgRef,
28532
+ gRef,
28533
+ setTransform,
28534
+ transformRef
28535
+ ]);
28536
+ }
28537
+ function useWindowDrag(enableDrag, svgRef, transformRef, dragActiveRef, dragNodeRef, onDragEnd) {
28538
+ (0, import_react.useEffect)(() => {
28539
+ if (!enableDrag) return;
28540
+ const handleWindowMove = (event) => {
28541
+ if (!dragActiveRef.current || !dragNodeRef.current) return;
28542
+ const svg = svgRef.current;
28543
+ if (!svg) return;
28544
+ const rect = svg.getBoundingClientRect();
28545
+ const t = transformRef.current;
28546
+ const x = (event.clientX - rect.left - t.x) / t.k;
28547
+ const y = (event.clientY - rect.top - t.y) / t.k;
28548
+ dragNodeRef.current.fx = x;
28549
+ dragNodeRef.current.fy = y;
28550
+ };
28551
+ const handleWindowUp = () => {
28552
+ if (!dragActiveRef.current) return;
28553
+ onDragEnd();
28554
+ dragNodeRef.current = null;
28555
+ dragActiveRef.current = false;
28556
+ };
28557
+ const handleWindowLeave = (event) => {
28558
+ if (event.relatedTarget === null) handleWindowUp();
28559
+ };
28560
+ window.addEventListener("mousemove", handleWindowMove);
28561
+ window.addEventListener("mouseup", handleWindowUp);
28562
+ window.addEventListener("mouseout", handleWindowLeave);
28563
+ window.addEventListener("blur", handleWindowUp);
28564
+ return () => {
28565
+ window.removeEventListener("mousemove", handleWindowMove);
28566
+ window.removeEventListener("mouseup", handleWindowUp);
28567
+ window.removeEventListener("mouseout", handleWindowLeave);
28568
+ window.removeEventListener("blur", handleWindowUp);
28569
+ };
28570
+ }, [
28571
+ enableDrag,
28572
+ svgRef,
28573
+ transformRef,
28574
+ dragActiveRef,
28575
+ dragNodeRef,
28576
+ onDragEnd
28577
+ ]);
28578
+ }
28579
+ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, links: initialLinks, width, height, enableZoom = true, enableDrag = true, onNodeClick, onNodeHover, onLinkClick, selectedNodeId, hoveredNodeId, defaultNodeColor = DEFAULT_NODE_COLOR, defaultNodeSize = DEFAULT_NODE_SIZE, defaultLinkColor = DEFAULT_LINK_COLOR, defaultLinkWidth = DEFAULT_LINK_WIDTH, showNodeLabels = true, showLinkLabels = false, className, manualLayout = false, onManualLayoutChange, packageBounds, layout: externalLayout, onLayoutChange }, ref) => {
28220
28580
  const svgRef = (0, import_react.useRef)(null);
28221
28581
  const gRef = (0, import_react.useRef)(null);
28222
28582
  const [transform, setTransform] = (0, import_react.useState)({
@@ -28232,7 +28592,7 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28232
28592
  const [layout, setLayout] = (0, import_react.useState)(externalLayout || "force");
28233
28593
  (0, import_react.useEffect)(() => {
28234
28594
  if (externalLayout && externalLayout !== layout) setLayout(externalLayout);
28235
- }, [externalLayout]);
28595
+ }, [externalLayout, layout]);
28236
28596
  const handleLayoutChange = (0, import_react.useCallback)((newLayout) => {
28237
28597
  setLayout(newLayout);
28238
28598
  onLayoutChange?.(newLayout);
@@ -28242,83 +28602,25 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28242
28602
  }, [enableDrag]);
28243
28603
  const nodes = import_react.useMemo(() => {
28244
28604
  if (!initialNodes || !initialNodes.length) return initialNodes;
28245
- const centerX = width / 2;
28246
- const centerY = height / 2;
28247
- if (layout === "force") return initialNodes.map((n) => ({
28248
- ...n,
28249
- x: Math.random() * width,
28250
- y: Math.random() * height
28251
- }));
28252
- if (layout === "circular") {
28253
- const radius = Math.min(width, height) * .35;
28254
- return initialNodes.map((n, i) => ({
28255
- ...n,
28256
- x: centerX + Math.cos(2 * Math.PI * i / initialNodes.length) * radius,
28257
- y: centerY + Math.sin(2 * Math.PI * i / initialNodes.length) * radius
28258
- }));
28259
- }
28260
- if (layout === "hierarchical") {
28261
- const cols = Math.ceil(Math.sqrt(initialNodes.length));
28262
- const spacingX = width / (cols + 1);
28263
- const spacingY = height / (Math.ceil(initialNodes.length / cols) + 1);
28264
- return initialNodes.map((n, i) => ({
28265
- ...n,
28266
- x: spacingX * (i % cols + 1),
28267
- y: spacingY * (Math.floor(i / cols) + 1)
28268
- }));
28269
- }
28270
- return initialNodes;
28605
+ const copy = initialNodes.map((n) => ({ ...n }));
28606
+ if (layout === "circular") applyCircularLayout(copy, width, height);
28607
+ else if (layout === "hierarchical") applyHierarchicalLayout(copy, width, height);
28608
+ else applyInitialForceLayout(copy, width, height);
28609
+ return copy;
28271
28610
  }, [
28272
28611
  initialNodes,
28273
28612
  width,
28274
28613
  height,
28275
28614
  layout
28276
28615
  ]);
28277
- const links = initialLinks;
28278
28616
  const restart = import_react.useCallback(() => {}, []);
28279
28617
  const stop = import_react.useCallback(() => {}, []);
28280
28618
  const setForcesEnabled = import_react.useCallback((enabled) => {}, []);
28281
28619
  (0, import_react.useEffect)(() => {
28282
28620
  if (!nodes || nodes.length === 0) return;
28283
- const applyLayout = () => {
28284
- const centerX = width / 2;
28285
- const centerY = height / 2;
28286
- if (layout === "circular") {
28287
- const radius = Math.min(width, height) * .35;
28288
- nodes.forEach((node, i) => {
28289
- const angle = 2 * Math.PI * i / nodes.length;
28290
- node.fx = centerX + Math.cos(angle) * radius;
28291
- node.fy = centerY + Math.sin(angle) * radius;
28292
- });
28293
- } else if (layout === "hierarchical") {
28294
- const groups = /* @__PURE__ */ new Map();
28295
- nodes.forEach((n) => {
28296
- const key = n.packageGroup || n.group || "root";
28297
- if (!groups.has(key)) groups.set(key, []);
28298
- groups.get(key).push(n);
28299
- });
28300
- const groupArray = Array.from(groups.entries());
28301
- const cols = Math.ceil(Math.sqrt(groupArray.length));
28302
- const groupSpacingX = width * .8 / cols;
28303
- const groupSpacingY = height * .8 / Math.ceil(groupArray.length / cols);
28304
- groupArray.forEach(([groupKey, groupNodes], gi) => {
28305
- const col = gi % cols;
28306
- const row = Math.floor(gi / cols);
28307
- const groupX = (col + .5) * groupSpacingX;
28308
- const groupY = (row + .5) * groupSpacingY;
28309
- if (groupKey.startsWith("pkg:") || groupKey === groupKey) groupNodes.forEach((n, ni) => {
28310
- const angle = 2 * Math.PI * ni / groupNodes.length;
28311
- const r = Math.min(80, 20 + groupNodes.length * 8);
28312
- n.fx = groupX + Math.cos(angle) * r;
28313
- n.fy = groupY + Math.sin(angle) * r;
28314
- });
28315
- });
28316
- }
28317
- try {
28318
- restart();
28319
- } catch (e) {}
28320
- };
28321
- applyLayout();
28621
+ if (layout === "circular") applyCircularLayout(nodes, width, height);
28622
+ else if (layout === "hierarchical") applyHierarchicalLayout(nodes, width, height);
28623
+ restart();
28322
28624
  }, [
28323
28625
  layout,
28324
28626
  nodes,
@@ -28327,10 +28629,8 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28327
28629
  restart
28328
28630
  ]);
28329
28631
  (0, import_react.useEffect)(() => {
28330
- try {
28331
- if (manualLayout || pinnedNodes.size > 0) setForcesEnabled(false);
28332
- else setForcesEnabled(true);
28333
- } catch (e) {}
28632
+ if (manualLayout || pinnedNodes.size > 0) setForcesEnabled(false);
28633
+ else setForcesEnabled(true);
28334
28634
  }, [
28335
28635
  manualLayout,
28336
28636
  pinnedNodes,
@@ -28368,7 +28668,7 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28368
28668
  let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
28369
28669
  nodes.forEach((node) => {
28370
28670
  if (node.x !== void 0 && node.y !== void 0) {
28371
- const size = node.size || 10;
28671
+ const size = node.size || DEFAULT_NODE_SIZE;
28372
28672
  minX = Math.min(minX, node.x - size);
28373
28673
  maxX = Math.max(maxX, node.x + size);
28374
28674
  minY = Math.min(minY, node.y - size);
@@ -28376,18 +28676,13 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28376
28676
  }
28377
28677
  });
28378
28678
  if (!isFinite(minX)) return;
28379
- const padding = 40;
28380
- const nodeWidth = maxX - minX;
28381
- const nodeHeight = maxY - minY;
28382
- const scale = Math.min((width - padding * 2) / nodeWidth, (height - padding * 2) / nodeHeight, 10);
28383
- const centerX = (minX + maxX) / 2;
28384
- const centerY = (minY + maxY) / 2;
28385
- const x = width / 2 - centerX * scale;
28386
- const y = height / 2 - centerY * scale;
28679
+ const scale = Math.min((width - FIT_VIEW_PADDING * 2) / (maxX - minX), (height - FIT_VIEW_PADDING * 2) / (maxY - minY), 10);
28680
+ const x = width / 2 - (minX + maxX) / 2 * scale;
28681
+ const y = height / 2 - (minY + maxY) / 2 * scale;
28387
28682
  if (gRef.current && svgRef.current) {
28388
28683
  const svg = select_default$1(svgRef.current);
28389
28684
  const newTransform = identity.translate(x, y).scale(scale);
28390
- svg.transition().duration(300).call(zoom_default().transform, newTransform);
28685
+ svg.transition().duration(TRANSITION_DURATION_MS).call(zoom_default().transform, newTransform);
28391
28686
  setTransform(newTransform);
28392
28687
  }
28393
28688
  },
@@ -28395,9 +28690,7 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28395
28690
  setDragMode: (enabled) => {
28396
28691
  internalDragEnabledRef.current = enabled;
28397
28692
  },
28398
- setLayout: (newLayout) => {
28399
- handleLayoutChange(newLayout);
28400
- },
28693
+ setLayout: (newLayout) => handleLayoutChange(newLayout),
28401
28694
  getLayout: () => layout
28402
28695
  }), [
28403
28696
  nodes,
@@ -28406,46 +28699,34 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28406
28699
  width,
28407
28700
  height,
28408
28701
  layout,
28409
- handleLayoutChange
28702
+ handleLayoutChange,
28703
+ setForcesEnabled
28410
28704
  ]);
28411
28705
  (0, import_react.useEffect)(() => {
28412
- try {
28413
- if (typeof onManualLayoutChange === "function") onManualLayoutChange(manualLayout);
28414
- } catch (e) {}
28706
+ if (typeof onManualLayoutChange === "function") onManualLayoutChange(manualLayout);
28415
28707
  }, [manualLayout, onManualLayoutChange]);
28708
+ useGraphZoom(svgRef, gRef, enableZoom, setTransform, transformRef);
28709
+ useWindowDrag(enableDrag, svgRef, transformRef, dragActiveRef, dragNodeRef, () => {
28710
+ setForcesEnabled(true);
28711
+ restart();
28712
+ });
28416
28713
  (0, import_react.useEffect)(() => {
28417
- if (!enableZoom || !svgRef.current || !gRef.current) return;
28418
- const svg = select_default$1(svgRef.current);
28714
+ if (!gRef.current) return;
28419
28715
  const g = select_default$1(gRef.current);
28420
- const zoom2 = zoom_default().scaleExtent([.1, 10]).on("zoom", (event) => {
28421
- g.attr("transform", event.transform);
28422
- transformRef.current = event.transform;
28423
- setTransform(event.transform);
28716
+ g.selectAll("g.node").each(function() {
28717
+ const datum = select_default$1(this).datum();
28718
+ if (!datum) return;
28719
+ select_default$1(this).attr("transform", `translate(${datum.x || 0},${datum.y || 0})`);
28424
28720
  });
28425
- svg.call(zoom2);
28426
- return () => {
28427
- svg.on(".zoom", null);
28428
- };
28429
- }, [enableZoom]);
28430
- (0, import_react.useEffect)(() => {
28431
- if (!gRef.current) return;
28432
- try {
28433
- const g = select_default$1(gRef.current);
28434
- g.selectAll("g.node").each(function() {
28435
- const datum = select_default$1(this).datum();
28436
- if (!datum) return;
28437
- select_default$1(this).attr("transform", `translate(${datum.x || 0},${datum.y || 0})`);
28438
- });
28439
- g.selectAll("line").each(function() {
28440
- const l = select_default$1(this).datum();
28441
- if (!l) return;
28442
- const s = typeof l.source === "object" ? l.source : nodes.find((n) => n.id === l.source) || l.source;
28443
- const t = typeof l.target === "object" ? l.target : nodes.find((n) => n.id === l.target) || l.target;
28444
- if (!s || !t) return;
28445
- select_default$1(this).attr("x1", s.x).attr("y1", s.y).attr("x2", t.x).attr("y2", t.y);
28446
- });
28447
- } catch (e) {}
28448
- }, [nodes, links]);
28721
+ g.selectAll("line").each(function() {
28722
+ const l = select_default$1(this).datum();
28723
+ if (!l) return;
28724
+ const s = typeof l.source === "object" ? l.source : nodes.find((n) => n.id === l.source) || l.source;
28725
+ const t = typeof l.target === "object" ? l.target : nodes.find((n) => n.id === l.target) || l.target;
28726
+ if (!s || !t) return;
28727
+ select_default$1(this).attr("x1", s.x).attr("y1", s.y).attr("x2", t.x).attr("y2", t.y);
28728
+ });
28729
+ }, [nodes, initialLinks]);
28449
28730
  const handleDragStart = (0, import_react.useCallback)((event, node) => {
28450
28731
  if (!enableDrag) return;
28451
28732
  event.preventDefault();
@@ -28455,96 +28736,46 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28455
28736
  node.fx = node.x;
28456
28737
  node.fy = node.y;
28457
28738
  setPinnedNodes((prev) => /* @__PURE__ */ new Set([...prev, node.id]));
28458
- try {
28459
- stop();
28460
- } catch (e) {}
28461
- }, [enableDrag, restart]);
28462
- (0, import_react.useEffect)(() => {
28463
- if (!enableDrag) return;
28464
- const handleWindowMove = (event) => {
28465
- if (!dragActiveRef.current || !dragNodeRef.current) return;
28466
- const svg = svgRef.current;
28467
- if (!svg) return;
28468
- const rect = svg.getBoundingClientRect();
28469
- const t = transformRef.current;
28470
- const x = (event.clientX - rect.left - t.x) / t.k;
28471
- const y = (event.clientY - rect.top - t.y) / t.k;
28472
- dragNodeRef.current.fx = x;
28473
- dragNodeRef.current.fy = y;
28474
- };
28475
- const handleWindowUp = () => {
28476
- if (!dragActiveRef.current) return;
28477
- try {
28478
- setForcesEnabled(true);
28479
- restart();
28480
- } catch (e) {}
28481
- dragNodeRef.current = null;
28482
- dragActiveRef.current = false;
28483
- };
28484
- const handleWindowLeave = (event) => {
28485
- if (event.relatedTarget === null) handleWindowUp();
28486
- };
28487
- window.addEventListener("mousemove", handleWindowMove);
28488
- window.addEventListener("mouseup", handleWindowUp);
28489
- window.addEventListener("mouseout", handleWindowLeave);
28490
- window.addEventListener("blur", handleWindowUp);
28491
- return () => {
28492
- window.removeEventListener("mousemove", handleWindowMove);
28493
- window.removeEventListener("mouseup", handleWindowUp);
28494
- window.removeEventListener("mouseout", handleWindowLeave);
28495
- window.removeEventListener("blur", handleWindowUp);
28496
- };
28497
- }, [enableDrag]);
28739
+ stop();
28740
+ }, [enableDrag, stop]);
28498
28741
  (0, import_react.useEffect)(() => {
28499
28742
  if (!gRef.current || !enableDrag) return;
28500
28743
  const g = select_default$1(gRef.current);
28501
- const dragBehavior = drag_default().on("start", function(event) {
28502
- try {
28503
- const id = ((event.sourceEvent && event.sourceEvent.target || event.target).closest?.("g.node"))?.getAttribute("data-id");
28504
- if (!id) return;
28505
- const node = nodes.find((n) => n.id === id);
28506
- if (!node) return;
28507
- if (!internalDragEnabledRef.current) return;
28508
- if (!event.active) restart();
28509
- dragActiveRef.current = true;
28510
- dragNodeRef.current = node;
28511
- node.fx = node.x;
28512
- node.fy = node.y;
28513
- setPinnedNodes((prev) => /* @__PURE__ */ new Set([...prev, node.id]));
28514
- } catch (e) {}
28515
- }).on("drag", function(event) {
28744
+ const dragBehavior = drag_default().on("start", (event) => {
28745
+ const id = ((event.sourceEvent && event.sourceEvent.target || event.target).closest?.("g.node"))?.getAttribute("data-id");
28746
+ if (!id || !internalDragEnabledRef.current) return;
28747
+ const node = nodes.find((n) => n.id === id);
28748
+ if (!node) return;
28749
+ if (!event.active) restart();
28750
+ dragActiveRef.current = true;
28751
+ dragNodeRef.current = node;
28752
+ node.fx = node.x;
28753
+ node.fy = node.y;
28754
+ setPinnedNodes((prev) => /* @__PURE__ */ new Set([...prev, node.id]));
28755
+ }).on("drag", (event) => {
28516
28756
  if (!dragActiveRef.current || !dragNodeRef.current) return;
28517
28757
  const svg = svgRef.current;
28518
28758
  if (!svg) return;
28519
28759
  const rect = svg.getBoundingClientRect();
28520
- const x = (event.sourceEvent.clientX - rect.left - transform.x) / transform.k;
28521
- const y = (event.sourceEvent.clientY - rect.top - transform.y) / transform.k;
28522
- dragNodeRef.current.fx = x;
28523
- dragNodeRef.current.fy = y;
28524
- }).on("end", function() {
28525
- try {
28526
- setForcesEnabled(true);
28527
- restart();
28528
- } catch (e) {}
28760
+ dragNodeRef.current.fx = (event.sourceEvent.clientX - rect.left - transform.x) / transform.k;
28761
+ dragNodeRef.current.fy = (event.sourceEvent.clientY - rect.top - transform.y) / transform.k;
28762
+ }).on("end", () => {
28763
+ setForcesEnabled(true);
28764
+ restart();
28529
28765
  });
28530
- try {
28531
- g.selectAll("g.node").call(dragBehavior);
28532
- } catch (e) {}
28766
+ g.selectAll("g.node").call(dragBehavior);
28533
28767
  return () => {
28534
- try {
28535
- g.selectAll("g.node").on(".drag", null);
28536
- } catch (e) {}
28768
+ g.selectAll("g.node").on(".drag", null);
28537
28769
  };
28538
28770
  }, [
28539
28771
  gRef,
28540
28772
  enableDrag,
28541
28773
  nodes,
28542
28774
  transform,
28543
- restart
28775
+ restart,
28776
+ setForcesEnabled,
28777
+ internalDragEnabledRef
28544
28778
  ]);
28545
- const handleNodeClick = (0, import_react.useCallback)((node) => {
28546
- onNodeClick?.(node);
28547
- }, [onNodeClick]);
28548
28779
  const handleNodeDoubleClick = (0, import_react.useCallback)((event, node) => {
28549
28780
  event.stopPropagation();
28550
28781
  if (!enableDrag) return;
@@ -28563,29 +28794,19 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28563
28794
  }
28564
28795
  restart();
28565
28796
  }, [enableDrag, restart]);
28566
- const handleCanvasDoubleClick = (0, import_react.useCallback)(() => {
28567
- nodes.forEach((node) => {
28568
- node.fx = null;
28569
- node.fy = null;
28570
- });
28571
- setPinnedNodes(/* @__PURE__ */ new Set());
28572
- restart();
28573
- }, [nodes, restart]);
28574
- const handleNodeMouseEnter = (0, import_react.useCallback)((node) => {
28575
- onNodeHover?.(node);
28576
- }, [onNodeHover]);
28577
- const handleNodeMouseLeave = (0, import_react.useCallback)(() => {
28578
- onNodeHover?.(null);
28579
- }, [onNodeHover]);
28580
- const handleLinkClick = (0, import_react.useCallback)((link) => {
28581
- onLinkClick?.(link);
28582
- }, [onLinkClick]);
28583
28797
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
28584
28798
  ref: svgRef,
28585
28799
  width,
28586
28800
  height,
28587
28801
  className: cn("bg-white dark:bg-gray-900", className),
28588
- onDoubleClick: handleCanvasDoubleClick,
28802
+ onDoubleClick: () => {
28803
+ nodes.forEach((n) => {
28804
+ n.fx = null;
28805
+ n.fy = null;
28806
+ });
28807
+ setPinnedNodes(/* @__PURE__ */ new Set());
28808
+ restart();
28809
+ },
28589
28810
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("marker", {
28590
28811
  id: "arrow",
28591
28812
  viewBox: "0 0 10 10",
@@ -28601,9 +28822,9 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28601
28822
  }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", {
28602
28823
  ref: gRef,
28603
28824
  children: [
28604
- links.map((link, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LinkItem_default, {
28825
+ initialLinks.map((link, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LinkItem_default, {
28605
28826
  link,
28606
- onClick: handleLinkClick,
28827
+ onClick: onLinkClick,
28607
28828
  defaultWidth: defaultLinkWidth,
28608
28829
  showLabel: showLinkLabels,
28609
28830
  nodes
@@ -28616,34 +28837,13 @@ var ForceDirectedGraph = (0, import_react.forwardRef)(({ nodes: initialNodes, li
28616
28837
  defaultNodeSize,
28617
28838
  defaultNodeColor,
28618
28839
  showLabel: showNodeLabels,
28619
- onClick: handleNodeClick,
28840
+ onClick: onNodeClick,
28620
28841
  onDoubleClick: handleNodeDoubleClick,
28621
- onMouseEnter: handleNodeMouseEnter,
28622
- onMouseLeave: handleNodeMouseLeave,
28842
+ onMouseEnter: (n) => onNodeHover?.(n),
28843
+ onMouseLeave: () => onNodeHover?.(null),
28623
28844
  onMouseDown: handleDragStart
28624
28845
  }, node.id)),
28625
- packageBounds && Object.keys(packageBounds).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", {
28626
- className: "package-boundaries",
28627
- pointerEvents: "none",
28628
- children: Object.entries(packageBounds).map(([pid, b]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
28629
- cx: b.x,
28630
- cy: b.y,
28631
- r: b.r,
28632
- fill: "rgba(148,163,184,0.06)",
28633
- stroke: "#475569",
28634
- strokeWidth: 2,
28635
- strokeDasharray: "6 6",
28636
- opacity: .9
28637
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
28638
- x: b.x,
28639
- y: Math.max(12, b.y - b.r + 14),
28640
- fill: "#475569",
28641
- fontSize: 11,
28642
- textAnchor: "middle",
28643
- pointerEvents: "none",
28644
- children: pid.replace(/^pkg:/, "")
28645
- })] }, pid))
28646
- })
28846
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PackageBoundaries, { packageBounds: packageBounds || {} })
28647
28847
  ]
28648
28848
  })]
28649
28849
  });
@@ -29089,4 +29289,4 @@ function App() {
29089
29289
  (0, import_client.createRoot)(document.getElementById("root")).render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(App, {}) }));
29090
29290
  //#endregion
29091
29291
 
29092
- //# sourceMappingURL=index-DbVV6ZUw.js.map
29292
+ //# sourceMappingURL=index-BG4XVj8A.js.map