feat: accept more nullish parameter in various methods by tbouffard · Pull Request #892 · maxGraph/maxGraph · GitHub
Skip to content

feat: accept more nullish parameter in various methods #892

Merged
tbouffard merged 4 commits into
mainfrom
feat/accept_undefined_and_null_in_various_places
Jul 30, 2025
Merged

feat: accept more nullish parameter in various methods #892
tbouffard merged 4 commits into
mainfrom
feat/accept_undefined_and_null_in_various_places

Conversation

@tbouffard

@tbouffard tbouffard commented Jul 29, 2025

Copy link
Copy Markdown
Member

This prepares the migration of the "Wires" story to TypeScript.

Add a new factory method in CellMarker to override the CellHighlight instance
Export missing ConnectionHandlerCellMarker class

The signature of some methods of the following classes now accepts null and/or undefined because their implementation
already supported it:

  • CellMixin
  • ConnectionHandler
  • EdgeMixin
  • Geometry.setTerminalPoint
  • GraphView.updateFixedTerminalPoint
  • VertexMixin

Improve JSDoc in various locations.

Summary by CodeRabbit

  • New Features

    • Added a new export for ConnectionHandlerCellMarker and made ConnectionHandler available as a default export.
  • Documentation

    • Improved and clarified JSDoc comments across multiple classes and methods for better readability and accuracy.
  • Refactor

    • Updated method signatures to allow more flexibility with optional parameters in cell and edge creation methods.
    • Enhanced extensibility by introducing a protected hook for customizing cell highlighting behavior.
    • Allowed terminal points to be explicitly set to null for greater control.
  • Style

    • Improved code formatting and consistency in comments and parameter naming.

This prepares the migration of the "Wires" story to TypeScript.

Add a new factory method in `CellMarker` to override the `CellHighlight` instance
Export missing `ConnectionHandlerCellMarker` class

The signature of some methods of the following classes now accepts null and/or undefined because their implementation
already supported it:
  - CellMixin
  - ConnectionHandler
  - EdgeMixin
  - Geometry.setTerminalPoint
  - GraphView.updateFixedTerminalPoint
  - VertexMixin

Improve JSDoc in various locations.
@tbouffard tbouffard added the enhancement New feature or request label Jul 29, 2025
@coderabbitai

coderabbitai Bot commented Jul 29, 2025

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
packages/core/src/view/plugins/ConnectionHandler.ts (1)

1296-1313: Guard against undefined edgeState.style before mutation

updateEdgeState writes to this.edgeState.style.* without confirming the object exists.
A defensive guard avoids a rare but possible TypeError when style hasn’t been initialised:

-    if (this.sourceConstraint?.point) {
+    if (this.edgeState.style && this.sourceConstraint?.point) {
       this.edgeState.style.exitX = this.sourceConstraint.point.x;
       this.edgeState.style.exitY = this.sourceConstraint.point.y;
     }
 
-    if (constraint?.point) {
+    if (this.edgeState.style && constraint?.point) {
       this.edgeState.style.entryX = constraint.point.x;
       this.edgeState.style.entryY = constraint.point.y;
     } else if (this.edgeState.style) {
       this.edgeState.style.entryX = 0;
       this.edgeState.style.entryY = 0;
     }

This keeps the tight loop allocation-free and avoids undefined access.

♻️ Duplicate comments (1)
packages/core/src/view/mixins/VertexMixin.ts (1)

118-118: Same non-null assertion concern as in EdgeMixin.

The non-null assertion id! poses the same potential runtime risk as identified in EdgeMixin.ts line 259, where an optional id parameter is asserted as non-null.

🧹 Nitpick comments (2)
packages/core/src/view/GraphView.ts (1)

1129-1136: JSDoc still implies the argument is always a ConnectionConstraint

Since constraint can now be null, the doc-comment should reflect this to avoid confusion.

- * @param constraint {@link ConnectionConstraint} that specifies the connection.
+ * @param constraint {@link ConnectionConstraint} | null – optional connection constraint.
packages/core/src/view/plugins/ConnectionHandler.ts (1)

715-741: Remove TODO or add JSDoc for getIconPosition

There’s still a “TODO: Document me!” banner above getIconPosition. Either finish the JSDoc (preferred) or drop the TODO to avoid noise.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95cdbc8 and e73c6eb.

📒 Files selected for processing (12)
  • packages/core/src/index.ts (1 hunks)
  • packages/core/src/view/GraphView.ts (1 hunks)
  • packages/core/src/view/cell/CellHighlight.ts (1 hunks)
  • packages/core/src/view/cell/CellMarker.ts (1 hunks)
  • packages/core/src/view/geometry/Geometry.ts (1 hunks)
  • packages/core/src/view/mixins/CellsMixin.type.ts (1 hunks)
  • packages/core/src/view/mixins/EdgeMixin.ts (1 hunks)
  • packages/core/src/view/mixins/EdgeMixin.type.ts (2 hunks)
  • packages/core/src/view/mixins/VertexMixin.ts (2 hunks)
  • packages/core/src/view/mixins/VertexMixin.type.ts (2 hunks)
  • packages/core/src/view/plugins/ConnectionHandler.ts (20 hunks)
  • packages/core/src/view/plugins/PanningHandler.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: tbouffard
PR: maxGraph/maxGraph#776
File: packages/core/src/view/AbstractGraph.ts:492-495
Timestamp: 2025-04-24T12:34:56.726Z
Learning: PR #776 focuses on refactoring to introduce AbstractGraph as a base class and moving code from Graph to AbstractGraph. Type improvements and other refinements should be addressed in future PRs to keep this one focused on the core architectural change.
Learnt from: tbouffard
PR: maxGraph/maxGraph#857
File: packages/core/src/view/plugins/SelectionHandler.ts:1081-1092
Timestamp: 2025-06-26T13:27:19.012Z
Learning: User tbouffard prefers to keep PRs focused on their main objective and defer implementation improvements or logic fixes to future dedicated PRs. For maxGraph, refactoring PRs like Dictionary→Map migration should not include unrelated logic improvements even when valid issues are identified in the migrated code.
Learnt from: tbouffard
PR: maxGraph/maxGraph#835
File: packages/html/stories/Orthogonal.stories.ts:114-117
Timestamp: 2025-05-26T12:34:54.318Z
Learning: The `null!` assertion pattern exists across multiple stories in the TypeScript migration and should be addressed systematically rather than in individual PRs.
Learnt from: tbouffard
PR: maxGraph/maxGraph#770
File: packages/core/src/view/cell/CellTracker.ts:99-101
Timestamp: 2025-04-18T07:02:31.931Z
Learning: In TypeScript, when implementing an interface, methods can have fewer parameters than declared in the interface due to TypeScript's structural typing system. Both omitting unused parameters entirely and prefixing them with underscore (e.g., _sender) are valid patterns in the maxGraph codebase.
Learnt from: tbouffard
PR: maxGraph/maxGraph#715
File: packages/html/stories/ZoomAndFit.stories.ts:0-0
Timestamp: 2025-03-14T06:01:22.326Z
Learning: For future improvements to the Graph component in maxGraph, tbouffard is interested in refactoring the `fit` method to use an object parameter pattern instead of multiple positional parameters, as the current approach makes the API harder to use when many parameters need to be specified with default values.
Learnt from: tbouffard
PR: maxGraph/maxGraph#593
File: .github/workflows/create-github-release.yml:42-42
Timestamp: 2025-01-28T16:22:25.804Z
Learning: In the GitHub release notes template for maxGraph, TODO comments are intentionally included to mark sections that must be reviewed by maintainers before publishing the release. These TODOs should not be removed or converted to validation steps as they are part of the release review process.
Learnt from: tbouffard
PR: maxGraph/maxGraph#791
File: packages/core/src/view/style/edge/Segment.ts:26-35
Timestamp: 2025-04-29T13:29:45.122Z
Learning: In the maxGraph project, JSDoc `{@link}` references to symbols don't need to be imported in the current file to work correctly. TypeDoc can resolve symbols across the entire project namespace, not just within the current file, which is common in modern documentation systems and IDEs.
Learnt from: tbouffard
PR: maxGraph/maxGraph#849
File: packages/html/stories/DragSource.stories.js:98-101
Timestamp: 2025-06-13T07:48:10.300Z
Learning: User tbouffard prefers answers in English; avoid switching to other languages in future replies.
packages/core/src/view/cell/CellMarker.ts (1)

Learnt from: tbouffard
PR: #776
File: packages/core/src/view/Graph.ts:85-92
Timestamp: 2025-04-24T12:34:10.366Z
Learning: The Graph class intentionally doesn't use collaborators (cellRenderer, selectionModel, view) from options in initializeCollaborators, as it's designed to replicate the previous implementation using only its factory methods for backward compatibility.

packages/core/src/view/GraphView.ts (2)

Learnt from: tbouffard
PR: #770
File: packages/core/src/view/cell/CellTracker.ts:99-101
Timestamp: 2025-04-18T07:02:31.931Z
Learning: In TypeScript, when implementing an interface, methods can have fewer parameters than declared in the interface due to TypeScript's structural typing system. Both omitting unused parameters entirely and prefixing them with underscore (e.g., _sender) are valid patterns in the maxGraph codebase.

Learnt from: tbouffard
PR: #776
File: packages/core/src/view/AbstractGraph.ts:492-495
Timestamp: 2025-04-24T12:34:56.726Z
Learning: PR #776 focuses on refactoring to introduce AbstractGraph as a base class and moving code from Graph to AbstractGraph. Type improvements and other refinements should be addressed in future PRs to keep this one focused on the core architectural change.

packages/core/src/view/mixins/CellsMixin.type.ts (1)

Learnt from: tbouffard
PR: #770
File: packages/core/src/view/cell/CellTracker.ts:99-101
Timestamp: 2025-04-18T07:02:31.931Z
Learning: In TypeScript, when implementing an interface, methods can have fewer parameters than declared in the interface due to TypeScript's structural typing system. Both omitting unused parameters entirely and prefixing them with underscore (e.g., _sender) are valid patterns in the maxGraph codebase.

packages/core/src/view/mixins/VertexMixin.ts (1)

Learnt from: tbouffard
PR: #770
File: packages/core/src/view/cell/CellTracker.ts:99-101
Timestamp: 2025-04-18T07:02:31.931Z
Learning: In TypeScript, when implementing an interface, methods can have fewer parameters than declared in the interface due to TypeScript's structural typing system. Both omitting unused parameters entirely and prefixing them with underscore (e.g., _sender) are valid patterns in the maxGraph codebase.

packages/core/src/view/mixins/EdgeMixin.type.ts (2)

Learnt from: tbouffard
PR: #770
File: packages/core/src/view/cell/CellTracker.ts:99-101
Timestamp: 2025-04-18T07:02:31.931Z
Learning: In TypeScript, when implementing an interface, methods can have fewer parameters than declared in the interface due to TypeScript's structural typing system. Both omitting unused parameters entirely and prefixing them with underscore (e.g., _sender) are valid patterns in the maxGraph codebase.

Learnt from: tbouffard
PR: #776
File: packages/core/src/view/AbstractGraph.ts:492-495
Timestamp: 2025-04-24T12:34:56.726Z
Learning: PR #776 focuses on refactoring to introduce AbstractGraph as a base class and moving code from Graph to AbstractGraph. Type improvements and other refinements should be addressed in future PRs to keep this one focused on the core architectural change.

packages/core/src/view/mixins/VertexMixin.type.ts (3)

Learnt from: tbouffard
PR: #770
File: packages/core/src/view/cell/CellTracker.ts:99-101
Timestamp: 2025-04-18T07:02:31.931Z
Learning: In TypeScript, when implementing an interface, methods can have fewer parameters than declared in the interface due to TypeScript's structural typing system. Both omitting unused parameters entirely and prefixing them with underscore (e.g., _sender) are valid patterns in the maxGraph codebase.

Learnt from: tbouffard
PR: #776
File: packages/core/src/view/AbstractGraph.ts:492-495
Timestamp: 2025-04-24T12:34:56.726Z
Learning: PR #776 focuses on refactoring to introduce AbstractGraph as a base class and moving code from Graph to AbstractGraph. Type improvements and other refinements should be addressed in future PRs to keep this one focused on the core architectural change.

Learnt from: tbouffard
PR: #776
File: packages/core/src/view/Graph.ts:85-92
Timestamp: 2025-04-24T12:34:10.366Z
Learning: The Graph class intentionally doesn't use collaborators (cellRenderer, selectionModel, view) from options in initializeCollaborators, as it's designed to replicate the previous implementation using only its factory methods for backward compatibility.

packages/core/src/view/mixins/EdgeMixin.ts (3)

Learnt from: tbouffard
PR: #770
File: packages/core/src/view/cell/CellTracker.ts:99-101
Timestamp: 2025-04-18T07:02:31.931Z
Learning: In TypeScript, when implementing an interface, methods can have fewer parameters than declared in the interface due to TypeScript's structural typing system. Both omitting unused parameters entirely and prefixing them with underscore (e.g., _sender) are valid patterns in the maxGraph codebase.

Learnt from: tbouffard
PR: #791
File: packages/website/docs/usage/edge-styles.md:59-63
Timestamp: 2025-04-29T13:30:18.686Z
Learning: In the EdgeStyles documentation, tbouffard prefers the existing text "A perimeter is a function matching the EdgeStyleFunction type" over suggestions that might create redundancy, even if terminology might be technically misaligned.

Learnt from: tbouffard
PR: #791
File: packages/website/docs/usage/edge-styles.md:59-63
Timestamp: 2025-04-29T13:32:14.572Z
Learning: In the EdgeStyles documentation, the sentence "A perimeter is a function matching the EdgeStyleFunction type" contains an incorrect term - "perimeter" should be replaced with "EdgeStyle" or "custom EdgeStyle" as the document is specifically about EdgeStyles.

packages/core/src/view/plugins/ConnectionHandler.ts (3)

Learnt from: tbouffard
PR: #791
File: packages/core/src/view/style/edge/Segment.ts:26-35
Timestamp: 2025-04-29T13:29:45.122Z
Learning: In the maxGraph project, JSDoc {@link} references to symbols don't need to be imported in the current file to work correctly. TypeDoc can resolve symbols across the entire project namespace, not just within the current file, which is common in modern documentation systems and IDEs.

Learnt from: tbouffard
PR: #776
File: packages/core/src/view/Graph.ts:85-92
Timestamp: 2025-04-24T12:34:10.366Z
Learning: The Graph class intentionally doesn't use collaborators (cellRenderer, selectionModel, view) from options in initializeCollaborators, as it's designed to replicate the previous implementation using only its factory methods for backward compatibility.

Learnt from: tbouffard
PR: #791
File: packages/website/docs/usage/edge-styles.md:59-63
Timestamp: 2025-04-29T13:30:18.686Z
Learning: In the EdgeStyles documentation, tbouffard prefers the existing text "A perimeter is a function matching the EdgeStyleFunction type" over suggestions that might create redundancy, even if terminology might be technically misaligned.

🧬 Code Graph Analysis (6)
packages/core/src/index.ts (3)
packages/html/stories/Anchors.stories.js (2)
  • MyCustomConnectionHandler (37-43)
  • createConnectionHandler (60-62)
packages/html/stories/FixedPoints.stories.js (2)
  • isConnectableCell (105-107)
  • MyCustomConnectionHandler (42-101)
packages/html/stories/Events.stories.js (1)
  • MyCustomConnectionHandler (40-43)
packages/core/src/view/plugins/PanningHandler.ts (1)
packages/core/src/view/event/InternalMouseEvent.ts (1)
  • isPopupTrigger (159-161)
packages/core/src/view/mixins/CellsMixin.type.ts (1)
packages/core/src/view/cell/Cell.ts (1)
  • Cell (66-888)
packages/core/src/view/mixins/VertexMixin.ts (1)
packages/core/src/view/cell/Cell.ts (1)
  • Cell (66-888)
packages/core/src/view/mixins/EdgeMixin.type.ts (2)
packages/core/src/view/cell/Cell.ts (1)
  • Cell (66-888)
packages/core/src/types.ts (1)
  • EdgeParametersValue (1066-1066)
packages/core/src/view/plugins/ConnectionHandler.ts (6)
packages/core/src/types.ts (2)
  • GraphPlugin (1179-1181)
  • MouseListenerSet (1211-1215)
packages/core/src/util/Constants.ts (3)
  • TOOLTIP_VERTICAL_OFFSET (75-75)
  • VALID_COLOR (150-150)
  • INVALID_COLOR (156-156)
packages/core/src/index.ts (1)
  • ConnectionHandlerCellMarker (52-52)
packages/html/stories/Anchors.stories.js (3)
  • MyCustomConnectionHandler (37-43)
  • createConnectionHandler (60-62)
  • MyCustomGraph (45-63)
packages/html/stories/FixedPoints.stories.js (2)
  • MyCustomConnectionHandler (42-101)
  • isConnectableCell (105-107)
packages/html/stories/Events.stories.js (2)
  • MyCustomConnectionHandler (40-43)
  • createConnectionHandler (56-58)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build (windows-2022)
  • GitHub Check: build (macos-14)
  • GitHub Check: build (ubuntu-24.04)
  • GitHub Check: build
🔇 Additional comments (16)
packages/core/src/view/cell/CellHighlight.ts (1)

231-231: LGTM: Documentation fix improves accuracy.

The JSDoc comment correction properly references CellState and InternalEvent.MARK instead of the previous typos/incomplete references.

packages/core/src/view/plugins/PanningHandler.ts (1)

267-269: LGTM: Documentation formatting enhancement.

The JSDoc formatting improvements with inline code backticks and proper @link references enhance readability and IDE integration.

packages/core/src/index.ts (1)

52-52: Good addition: Improves API surface for connection handling.

Making ConnectionHandlerCellMarker available as a named export enables external customization of connection handling, which aligns with the usage patterns seen in the story files.

packages/core/src/view/cell/CellMarker.ts (1)

132-141: Excellent extensibility improvement using factory method pattern.

The introduction of the createCellHighlight factory method enables subclasses to customize the CellHighlight instance creation without overriding the entire constructor. This follows established patterns in the codebase for enabling extensibility.

packages/core/src/view/geometry/Geometry.ts (1)

195-195: Good type accuracy improvement.

Making the point parameter nullable (Point | null) accurately reflects the method's implementation and the nullable nature of the sourcePoint and targetPoint properties it sets. This enhances type safety and API flexibility.

packages/core/src/view/GraphView.ts (1)

1138-1146: Signature widening and cast removal look good

The parameter now explicitly allows null and the superfluous <Point> cast has been dropped. This aligns with the return type Point | null from getFixedTerminalPoint and with the PR’s intent to accept nullish values. No further action needed.

packages/core/src/view/mixins/CellsMixin.type.ts (1)

302-302: LGTM! Parameter made appropriately optional.

Making the parent parameter optional in the addCell method signature improves API flexibility while maintaining type safety. This change aligns well with the PR's objective of accepting more nullish parameters.

packages/core/src/view/mixins/EdgeMixin.ts (2)

250-255: LGTM! Unused parameters appropriately marked.

Prefixing unused parameters with underscores (_parent, _source, _target) follows TypeScript best practices and aligns with existing maxGraph patterns.


259-259: Verify id! assertion safety in EdgeMixin (and VertexMixin)

The non-null assertion (id!) may pass an actual undefined into setId at runtime. Automated searches didn’t locate the setId signature or its handling of undefined, so please manually confirm:

• Whether setId’s parameter is truly optional (e.g. id?: string) and
• How setId(undefined) behaves (auto-generates a new ID vs. assigns undefined)

If id can be undefined here, either guard the call or supply a default/generated ID before invoking:

packages/core/src/view/mixins/EdgeMixin.ts:259

-   edge.setId(id!); // the auto-generated id is done when adding the cell to the model
+   if (id != null) {
+     edge.setId(id);
+   }
+   // else rely on model to generate an ID when adding the cell

Repeat the same check in VertexMixin.ts.

packages/core/src/view/mixins/VertexMixin.ts (1)

101-103: LGTM! Parameters made appropriately optional.

Making the _parent, id, and value parameters optional aligns with the updated type signatures and improves API flexibility.

packages/core/src/view/mixins/EdgeMixin.type.ts (2)

186-192: LGTM! Method signature appropriately relaxed.

Making the parent, id, and value parameters optional in insertEdge improves API flexibility while maintaining type safety. The changes are well-coordinated with the implementation.


216-222: LGTM! Consistent parameter flexibility for createEdge.

The optional parameters in createEdge align well with the implementation changes and provide consistent API flexibility across edge creation methods.

packages/core/src/view/mixins/VertexMixin.type.ts (2)

92-102: LGTM! Consistent API flexibility for insertVertex.

Making the parent, id, and value parameters optional maintains consistency with the edge methods and provides the same flexible API experience across vertex operations.


165-175: LGTM! Well-coordinated createVertex signature.

The optional parameters in createVertex complete the consistent pattern across all cell creation methods, maintaining type safety while improving API flexibility.

packages/core/src/view/plugins/ConnectionHandler.ts (2)

205-208: Verify export strategy – default vs named

The class is now declared with export default, while packages/core/src/index.ts appears to re-export ConnectionHandler as a named export.
Having both export default and a re-exported name is fine, but please double-check that:

  1. The index file does not add a second export default (rollup/tsc will complain).
  2. External consumers keep using a single, canonical import style to avoid duplication in bundle output.

No change requested if the build remains clean; this is a heads-up.


2014-2029: 👍 Good call on exporting ConnectionHandlerCellMarker

Promoting the marker to a public export solves long-standing extension friction and aligns with storybook examples that subclass it.

@sonarqubecloud

Copy link
Copy Markdown

@tbouffard tbouffard merged commit 74e44bc into main Jul 30, 2025
2 checks passed
@tbouffard tbouffard deleted the feat/accept_undefined_and_null_in_various_places branch July 30, 2025 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant