@carlonicora/nextjs-jsonapi 1.99.0 → 1.100.1

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.
@@ -47,7 +47,7 @@ import {
47
47
  TabsList,
48
48
  TabsTrigger,
49
49
  useCurrentUserContext
50
- } from "../chunk-CDNVUON3.mjs";
50
+ } from "../chunk-J767HTWG.mjs";
51
51
  import {
52
52
  getRoleId,
53
53
  getStripePublishableKey
@@ -6460,6 +6460,14 @@ import * as dagre from "dagre";
6460
6460
  var DEFAULT_RANKDIR = "LR";
6461
6461
  var DEFAULT_NODESEP = 50;
6462
6462
  var DEFAULT_RANKSEP = 120;
6463
+ var MIN_NODESEP = 20;
6464
+ var MAX_NODESEP = 400;
6465
+ var MIN_RANKSEP = 40;
6466
+ var MAX_RANKSEP = 600;
6467
+ var MIN_FACTOR = 0.25;
6468
+ var MAX_FACTOR = 4;
6469
+ var DEFAULT_TOLERANCE = 0.05;
6470
+ var DEFAULT_MAX_ITERATIONS = 4;
6463
6471
  var TITLE_PX_PER_CHAR_16 = 8;
6464
6472
  var NAME_PX_PER_CHAR_12 = 6.5;
6465
6473
  var NAME_PX_PER_CHAR_16_BOLD = 8;
@@ -6479,8 +6487,11 @@ function linkEndpointId(end) {
6479
6487
  return typeof end === "string" ? end : end.id;
6480
6488
  }
6481
6489
  __name(linkEndpointId, "linkEndpointId");
6482
- function computeLayeredLayout(nodes, links, opts) {
6483
- if (nodes.length === 0) return /* @__PURE__ */ new Map();
6490
+ function clamp(value, min, max) {
6491
+ return Math.min(Math.max(value, min), max);
6492
+ }
6493
+ __name(clamp, "clamp");
6494
+ function runDagreOnce(nodes, links, opts) {
6484
6495
  const rankdir = opts.rankdir ?? DEFAULT_RANKDIR;
6485
6496
  const nodesep = opts.nodesep ?? DEFAULT_NODESEP;
6486
6497
  const ranksep = opts.ranksep ?? DEFAULT_RANKSEP;
@@ -6508,18 +6519,88 @@ function computeLayeredLayout(nodes, links, opts) {
6508
6519
  return null;
6509
6520
  }
6510
6521
  const positions = /* @__PURE__ */ new Map();
6522
+ let xMin = Infinity;
6523
+ let xMax = -Infinity;
6524
+ let yMin = Infinity;
6525
+ let yMax = -Infinity;
6511
6526
  for (const node of nodes) {
6512
6527
  const laid = g.node(node.id);
6513
6528
  if (laid && Number.isFinite(laid.x) && Number.isFinite(laid.y)) {
6514
6529
  positions.set(node.id, { x: laid.x, y: laid.y });
6530
+ const halfW = (laid.width ?? opts.minNodeWidth) / 2;
6531
+ const halfH = (laid.height ?? opts.minNodeHeight) / 2;
6532
+ xMin = Math.min(xMin, laid.x - halfW);
6533
+ xMax = Math.max(xMax, laid.x + halfW);
6534
+ yMin = Math.min(yMin, laid.y - halfH);
6535
+ yMax = Math.max(yMax, laid.y + halfH);
6515
6536
  }
6516
6537
  }
6517
- return positions;
6538
+ const bbox = positions.size === 0 ? { width: 0, height: 0 } : { width: Math.max(0, xMax - xMin), height: Math.max(0, yMax - yMin) };
6539
+ return { positions, bbox };
6540
+ }
6541
+ __name(runDagreOnce, "runDagreOnce");
6542
+ function computeLayeredLayout(nodes, links, opts) {
6543
+ if (nodes.length === 0) return /* @__PURE__ */ new Map();
6544
+ const result = runDagreOnce(nodes, links, opts);
6545
+ return result ? result.positions : null;
6518
6546
  }
6519
6547
  __name(computeLayeredLayout, "computeLayeredLayout");
6548
+ function fitLayeredLayoutToAspectRatio(nodes, links, opts) {
6549
+ if (nodes.length === 0) return /* @__PURE__ */ new Map();
6550
+ if (!Number.isFinite(opts.targetAspectRatio) || opts.targetAspectRatio <= 0) {
6551
+ return computeLayeredLayout(nodes, links, opts);
6552
+ }
6553
+ const maxIterations = opts.maxIterations ?? DEFAULT_MAX_ITERATIONS;
6554
+ const tolerance = opts.tolerance ?? DEFAULT_TOLERANCE;
6555
+ const rankdir = opts.rankdir ?? DEFAULT_RANKDIR;
6556
+ const isHorizontalFlow = rankdir === "LR" || rankdir === "RL";
6557
+ let nodesep = opts.nodesep ?? DEFAULT_NODESEP;
6558
+ let ranksep = opts.ranksep ?? DEFAULT_RANKSEP;
6559
+ let best = null;
6560
+ for (let i = 0; i < maxIterations; i++) {
6561
+ const result = runDagreOnce(nodes, links, {
6562
+ ...opts,
6563
+ nodesep,
6564
+ ranksep
6565
+ });
6566
+ if (!result) return best ? best.positions : null;
6567
+ best = result;
6568
+ if (result.positions.size <= 1) return result.positions;
6569
+ const { width, height } = result.bbox;
6570
+ if (width === 0 || height === 0) return result.positions;
6571
+ const currentAspect = width / height;
6572
+ const ratio = opts.targetAspectRatio / currentAspect;
6573
+ if (Math.abs(ratio - 1) < tolerance) return result.positions;
6574
+ const factor = clamp(Math.sqrt(ratio), MIN_FACTOR, MAX_FACTOR);
6575
+ if (isHorizontalFlow) {
6576
+ ranksep = clamp(ranksep * factor, MIN_RANKSEP, MAX_RANKSEP);
6577
+ nodesep = clamp(nodesep / factor, MIN_NODESEP, MAX_NODESEP);
6578
+ } else {
6579
+ ranksep = clamp(ranksep / factor, MIN_RANKSEP, MAX_RANKSEP);
6580
+ nodesep = clamp(nodesep * factor, MIN_NODESEP, MAX_NODESEP);
6581
+ }
6582
+ }
6583
+ return best ? best.positions : null;
6584
+ }
6585
+ __name(fitLayeredLayoutToAspectRatio, "fitLayeredLayoutToAspectRatio");
6520
6586
 
6521
6587
  // src/hooks/useCustomD3Graph.tsx
6522
6588
  import { jsx as jsx49 } from "react/jsx-runtime";
6589
+ var TITLE_PX_PER_CHAR_162 = 8;
6590
+ var NAME_PX_PER_CHAR_122 = 6.5;
6591
+ var NAME_PX_PER_CHAR_16_BOLD2 = 8;
6592
+ var SUBTITLE_PX_PER_CHAR_112 = 6;
6593
+ var LABEL_PADDING_PX2 = 16;
6594
+ function estimateLabelWidth2(node) {
6595
+ if (node.subtitle) {
6596
+ const titleWidth = (node.name?.length ?? 0) * TITLE_PX_PER_CHAR_162;
6597
+ const subtitleWidth = node.subtitle.length * SUBTITLE_PX_PER_CHAR_112;
6598
+ return Math.max(titleWidth, subtitleWidth) + LABEL_PADDING_PX2;
6599
+ }
6600
+ const perChar = node.bold ? NAME_PX_PER_CHAR_16_BOLD2 : NAME_PX_PER_CHAR_122;
6601
+ return (node.name?.length ?? 0) * perChar + LABEL_PADDING_PX2;
6602
+ }
6603
+ __name(estimateLabelWidth2, "estimateLabelWidth");
6523
6604
  function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, options, loadingNodeIds, containerKey) {
6524
6605
  const svgRef = useRef8(null);
6525
6606
  const zoomRef = useRef8(null);
@@ -6653,7 +6734,15 @@ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, options, lo
6653
6734
  let layeredPositionsApplied = false;
6654
6735
  if (layoutMode === "layered") {
6655
6736
  const layeredOpts = options?.layered ?? {};
6656
- const positions = computeLayeredLayout(visibleNodes, visibleLinks, {
6737
+ const useFit = layeredOpts.fitContainer === true && width > 0 && height > 0;
6738
+ const positions = useFit ? fitLayeredLayoutToAspectRatio(visibleNodes, visibleLinks, {
6739
+ rankdir: layeredOpts.rankdir ?? "LR",
6740
+ nodesep: layeredOpts.nodesep,
6741
+ ranksep: layeredOpts.ranksep,
6742
+ minNodeWidth: nodeRadius * 2,
6743
+ minNodeHeight: nodeRadius * 2,
6744
+ targetAspectRatio: width / height
6745
+ }) : computeLayeredLayout(visibleNodes, visibleLinks, {
6657
6746
  rankdir: layeredOpts.rankdir ?? "LR",
6658
6747
  nodesep: layeredOpts.nodesep,
6659
6748
  ranksep: layeredOpts.ranksep,
@@ -6798,9 +6887,12 @@ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, options, lo
6798
6887
  simulation = d3.forceSimulation(visibleNodes).force(
6799
6888
  "link",
6800
6889
  d3.forceLink(visibleLinks).id((d) => d.id).distance(nodeRadius * 3).strength(0.1)
6801
- ).force("charge", d3.forceManyBody().strength(-500).distanceMax(300)).force("collision", d3.forceCollide().radius(nodeRadius * 1.2)).force("center", d3.forceCenter(width / 2, height / 2).strength(0.1));
6890
+ ).force("charge", d3.forceManyBody().strength(-2500).distanceMax(800)).force(
6891
+ "collision",
6892
+ d3.forceCollide().radius((d) => Math.max(nodeRadius * 1.1, estimateLabelWidth2(d) / 2 + 8))
6893
+ ).force("center", d3.forceCenter(width / 2, height / 2).strength(0.1));
6802
6894
  simulation.stop();
6803
- for (let i = 0; i < 100; i++) {
6895
+ for (let i = 0; i < 300; i++) {
6804
6896
  simulation.tick();
6805
6897
  }
6806
6898
  visibleNodes.forEach((node2) => {
@@ -6963,6 +7055,7 @@ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, options, lo
6963
7055
  options?.layered?.rankdir,
6964
7056
  options?.layered?.nodesep,
6965
7057
  options?.layered?.ranksep,
7058
+ options?.layered?.fitContainer,
6966
7059
  loadingNodeIds,
6967
7060
  onNodeClick
6968
7061
  ]);
@@ -9400,7 +9493,7 @@ import { useRef as useRef15 } from "react";
9400
9493
  import dynamic from "next/dynamic";
9401
9494
  import React14 from "react";
9402
9495
  import { jsx as jsx73 } from "react/jsx-runtime";
9403
- var BlockNoteEditor = dynamic(() => import("./BlockNoteEditor-IBV3KBQM.mjs"), {
9496
+ var BlockNoteEditor = dynamic(() => import("./BlockNoteEditor-OBWSYICZ.mjs"), {
9404
9497
  ssr: false
9405
9498
  });
9406
9499
  var BlockNoteEditorContainer = React14.memo(/* @__PURE__ */ __name(function EditorContainer(props) {
@@ -21815,6 +21908,7 @@ export {
21815
21908
  registerTableGenerator,
21816
21909
  useTableGenerator,
21817
21910
  computeLayeredLayout,
21911
+ fitLayeredLayoutToAspectRatio,
21818
21912
  useCustomD3Graph,
21819
21913
  SocketContext,
21820
21914
  SocketProvider,
@@ -22314,4 +22408,4 @@ export {
22314
22408
  useOAuthClients,
22315
22409
  useOAuthClient
22316
22410
  };
22317
- //# sourceMappingURL=chunk-CDNVUON3.mjs.map
22411
+ //# sourceMappingURL=chunk-J767HTWG.mjs.map