Skip to content

Conversation

@tbouffard
Copy link
Member

@tbouffard tbouffard commented May 5, 2025

Remove hard-coded EdgeStyle references throughout the codebase to enable proper tree-shaking.
Previously, all built-in EdgeStyle implementations were always included in application bundles.
Now, only registered EdgeStyle implementations are bundled, reducing application size by up to 17kB when no EdgeStyles are used.

This is implemented by:

  • Creating a dedicated EdgeStyleRegistry to register EdgeStyle with metadata
  • Introducing PerimeterRegistry to manage Perimeter registrations separately
  • Removing StyleRegistry which previously handled both concerns

Additional improvements:

  • Add dedicated unregister functions for each registry type, allowing independent management of EdgeStyle and Perimeter registrations
  • Create BaseRegistry to share common functionality between all style registries

BREAKING CHANGES: StyleRegistry has been removed. Use EdgeStyleRegistry and PerimeterRegistry instead.
The methods of the new registries are also named differently.

Notes

Closes #767

Impact on the size of the examples

Example v0.19.0 With #806 With #809
js-example 475.30 kB 469.8 kB 470.56 kB
js-example-selected-features 415.10 kB 410.18 kB 393.27 kB
js-example-without-default 347.33 kB 342.69 kB 325.79 kB
ts-example 438.64 kB 434.80 kB 435.46 kB
ts-example-selected-features 380.70 kB 377.11 kB 369.30 kB
ts-example-without-default 329.90 kB 326.43 kB 309.40 kB

Analysis

  • maximum decrease: 17 kB
  • js-example-selected-features doesn't register and use EdgeStyle, so the decrease is maximal (17 kB)
  • ts-example-selected-features only regsiters EdgeStyle.OrthConnector which depends on EdgeStyle.Segment (which is then bundled). The decrease is about 8 kB.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced dedicated registries for edge styles and perimeters, allowing for more precise management and registration through EdgeStyleRegistry and PerimeterRegistry.
    • Edge styles can now be registered with metadata, enabling advanced configuration and improved handler selection.
  • Bug Fixes

    • Improved isolation and accuracy in test suites by explicitly registering and unregistering styles before and after tests.
  • Documentation

    • Updated all references and examples to use EdgeStyleRegistry and PerimeterRegistry instead of the removed StyleRegistry.
    • Added guidance on registering edge styles with the required metadata.
  • Chores

    • Refactored internal logic to utilize the new registries, removing the generic style registry for clearer, modular architecture.
    • Added new utility functions and interfaces to support registry operations and metadata handling.
    • Adjusted build configuration chunk size warning limits in example projects.

Remove hard-coded EdgeStyle references throughout the codebase to enable proper tree-shaking.
Previously, all built-in EdgeStyle implementations were always included in application bundles.
Now, only registered EdgeStyle implementations are bundled, reducing application size by up to 17kB when no EdgeStyles are used.

This is implemented by:
- Creating a dedicated EdgeStyleRegistry to register EdgeStyle with metadata
- Introducing PerimeterRegistry to manage Perimeter registrations separately
- Removing StyleRegistry which previously handled both concerns

Additional improvements:
- Add dedicated unregister functions for each registry type, allowing independent management of EdgeStyle and Perimeter registrations
- Create BaseRegistry to share common functionality between all style registries

BREAKING CHANGES: `StyleRegistry` has been removed. Use `EdgeStyleRegistry` and `PerimeterRegistry` instead.
The methods of the new registries are also named differently.
@tbouffard tbouffard added the enhancement New feature or request label May 5, 2025
@coderabbitai
Copy link

coderabbitai bot commented May 5, 2025

Walkthrough

This change removes the generic StyleRegistry and introduces two dedicated registries: EdgeStyleRegistry for edge styles (with metadata) and PerimeterRegistry for perimeters. All code, documentation, and tests are updated to use these new registries. The Graph.createEdgeHandler and Graph.isOrthogonal methods now use EdgeStyleRegistry metadata instead of hardcoded logic.

Changes

File(s) Change Summary
packages/core/src/view/style/StyleRegistry.ts Removed the StyleRegistry class and its static methods.
packages/core/src/internal/BaseRegistry.ts
packages/core/__tests__/internal/BaseRegistry.test.ts
Introduced a generic BaseRegistry class for registries and added tests for its functionality.
packages/core/src/view/style/edge/EdgeStyleRegistry.ts
packages/core/__tests__/view/style/EdgeStyleRegistry.test.ts
Added EdgeStyleRegistry class with metadata support and corresponding tests.
packages/core/src/view/style/perimeter/PerimeterRegistry.ts Added PerimeterRegistry as a dedicated registry for perimeter functions.
packages/core/src/view/style/register.ts Refactored registration/unregistration to use new registries and metadata; split unregister functions.
packages/core/src/view/AbstractGraph.ts Refactored createEdgeHandler and isOrthogonal to use EdgeStyleRegistry metadata instead of hardcoded checks.
packages/core/src/view/GraphView.ts Updated to use EdgeStyleRegistry and PerimeterRegistry for style lookups.
packages/core/src/index.ts Updated exports to remove StyleRegistry and add new registries.
packages/core/src/serialization/codecs/GraphViewCodec.ts
packages/core/src/serialization/codecs/StylesheetCodec.ts
packages/core/src/serialization/codecs/utils.ts
Updated style name resolution to use new registries and added a utility for querying all registries.
packages/core/src/types.ts Updated documentation, added registry interfaces/types, and clarified edge style registration requirements.
packages/core/src/view/style/edge/Elbow.ts
.../EntityRelation.ts
.../Loop.ts
.../Manhattan.ts
.../Orthogonal.ts
.../Segment.ts
.../SideToSide.ts
.../TopToBottom.ts
Updated documentation comments to reference EdgeStyleRegistry and required metadata.
packages/core/src/view/style/perimeter/EllipsePerimeter.ts
.../HexagonPerimeter.ts
.../RectanglePerimeter.ts
.../RhombusPerimeter.ts
.../TrianglePerimeter.ts
Updated documentation comments to reference PerimeterRegistry.
packages/core/src/view/style/marker/EdgeMarkerRegistry.ts Clarified JSDoc for marker creation (no logic change).
packages/core/__tests__/view/Graph.test.ts
.../GraphView.test.ts
Refactored tests to use new registries and added/updated tests for handler creation and orthogonality.
packages/html/stories/Wires.stories.js
packages/js-example-selected-features/src/index.js
packages/ts-example-selected-features/src/main.ts
Updated example and story code to use new registries and registration APIs.
packages/website/docs/usage/edge-styles.md
.../global-configuration.md
.../perimeters.md
Updated documentation to describe the new registries, registration APIs, and breaking changes.
CHANGELOG.md Documented removal of StyleRegistry and migration to new registries.
packages/ts-example-selected-features/vite.config.js
packages/ts-example-without-defaults/vite.config.js
packages/ts-example/vite.config.js
Adjusted Vite chunk size warning limits (unrelated to registry changes).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant EdgeStyleRegistry
    participant Graph
    participant EdgeHandler
    participant ElbowEdgeHandler
    participant EdgeSegmentHandler

    User->>EdgeStyleRegistry: add('customStyle', fn, {handlerKind: 'elbow', isOrthogonal: true})
    User->>Graph: createEdgeHandler(cellState)
    Graph->>EdgeStyleRegistry: getHandlerKind(cellState.style.edgeStyle)
    alt handlerKind == 'elbow'
        Graph->>ElbowEdgeHandler: new(state)
    else handlerKind == 'segment'
        Graph->>EdgeSegmentHandler: new(state)
    else
        Graph->>EdgeHandler: new(state)
    end

    User->>Graph: isOrthogonal(cellState)
    Graph->>EdgeStyleRegistry: isOrthogonal(cellState.style.edgeStyle)
    EdgeStyleRegistry-->>Graph: true/false
Loading

Assessment against linked issues

Objective (Issue #767) Addressed Explanation
Remove hardcoded EdgeStyle checks from Graph.createEdgeHandler and Graph.isOrthogonal and use registry metadata
Introduce EdgeStyleRegistry with metadata for handler kind and orthogonality
Restrict StyleRegistry to perimeters only (now PerimeterRegistry)
Update docs and JSDoc to describe registration requirements and breaking changes
Add unregister functions for new registries

Possibly related PRs

Suggested labels

refactor


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 977f5e8 and 99a6a22.

📒 Files selected for processing (2)
  • packages/core/__tests__/internal/BaseRegistry.test.ts (1 hunks)
  • packages/core/src/internal/BaseRegistry.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/tests/internal/BaseRegistry.test.ts
  • packages/core/src/internal/BaseRegistry.ts
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build
  • GitHub Check: build (windows-2022)
  • GitHub Check: build (macos-14)
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (11)
packages/core/src/view/style/marker/EdgeMarkerRegistry.ts (1)

53-58: Enhance JSDoc with explicit @param and @returns tags
The expanded description is helpful, but to improve IDE support and generated docs, please add explicit @param entries for each method parameter and an @returns tag describing the MarkerFunction | null return value.

packages/core/src/view/style/edge/Orthogonal.ts (1)

147-152: Updated documentation to reference EdgeStyleRegistry
The doc now correctly instructs users to register OrthogonalConnector under orthogonalEdgeStyle in EdgeStyleRegistry with handlerKind: 'segment' and isOrthogonal: true.

Nitpick: remove the double space before "in" on the second line.

- * **IMPORTANT**: When registering it manually  in {@link EdgeStyleRegistry}, the following metadata must be used:
+ * **IMPORTANT**: When registering it manually in {@link EdgeStyleRegistry}, the following metadata must be used:
packages/core/src/view/style/edge/Elbow.ts (1)

30-35: Documentation updated for EdgeStyleRegistry usage
The comments now reference elbowEdgeStyle in EdgeStyleRegistry and list the required metadata (handlerKind: 'elbow', isOrthogonal: true).

Nitpick: remove the extra space before "in" on the metadata line.

- * **IMPORTANT**: When registering it manually  in {@link EdgeStyleRegistry}, the following metadata must be used:
+ * **IMPORTANT**: When registering it manually in {@link EdgeStyleRegistry}, the following metadata must be used:
packages/core/src/view/style/edge/Segment.ts (1)

30-35: Documentation updated for EdgeStyleRegistry usage
The doc correctly instructs registering SegmentConnector under segmentEdgeStyle with handlerKind: 'segment' and isOrthogonal: true.

Nitpick: remove the double space before "in" on the metadata line.

- * **IMPORTANT**: When registering it manually  in {@link EdgeStyleRegistry}, the following metadata must be used:
+ * **IMPORTANT**: When registering it manually in {@link EdgeStyleRegistry}, the following metadata must be used:
packages/website/docs/usage/global-configuration.md (1)

55-58: Documentation correctly updated for the new registry structure.

The documentation now accurately reflects the architectural changes by:

  1. Listing EdgeStyleRegistry as the dedicated registry for edge styles since 0.20.0
  2. Listing PerimeterRegistry as the dedicated registry for perimeters since 0.20.0
  3. Noting that both were previously managed by StyleRegistry

This makes the breaking change clear to users.

Fix list indentation.

The indentation of list items is inconsistent with the rest of the document.

Apply this fix:

-  - `EdgeStyleRegistry`: edge styles (since 0.20.0, previously managed by `StyleRegistry`)
+- `EdgeStyleRegistry`: edge styles (since 0.20.0, previously managed by `StyleRegistry`)
 - `CellRenderer`: shapes
 - `MarkerShape`: edge markers (also known as `startArrow` and `endArrow` in `CellStateStyle`)
-  - `PerimeterRegistry`: perimeters (since 0.20.0, previously managed by `StyleRegistry`)
+- `PerimeterRegistry`: perimeters (since 0.20.0, previously managed by `StyleRegistry`)
 - `StencilShapeRegistry`: stencil shapes
🧰 Tools
🪛 LanguageTool

[uncategorized] ~55-~55: Loose punctuation mark.
Context: ...configurations. - EdgeStyleRegistry: edge styles (since 0.20.0, previously m...

(UNLIKELY_OPENING_PUNCTUATION)

🪛 markdownlint-cli2 (0.17.2)

55-55: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


56-56: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


57-57: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


58-58: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)

packages/core/src/view/style/edge/EdgeStyleRegistry.ts (2)

36-41: Duplicate registration silently overwrites metadata

super.add(name, edgeStyle) will replace any existing entry for name, but the previous handler/orthogonal metadata in the internal maps is not removed, leading to:

  • stale metadata referenced by old edgeStyle functions,
  • inconsistent state if the same name is re-used with a different function.

Consider cleaning the old entries first:

+ const previous = this.get(name);
+ if (previous) {
+   this.handlerMapping.delete(previous);
+   this.orthogonalStates.delete(previous);
+ }
 super.add(name, edgeStyle);

Alternatively, throw if name is already registered to catch mistakes early.


61-69: clear() is publicly exposed despite the JSDoc warning

The JSDoc states this should not be called directly, yet it is public and used by external helpers.
Either:

  1. Rename to resetInternal() and make it protected, or
  2. Remove the warning and document that higher-level helpers may call it.

At present the API sends mixed signals to users.

packages/core/src/view/style/register.ts (2)

42-58: Defaulting isOrthogonal to true may hide configuration mistakes

The spread clause forces isOrthogonal to true when the caller omits the flag:

isOrthogonal: metadata.isOrthogonal ?? true

While convenient, it silently marks all edge styles orthogonal except those explicitly set to false (only loopEdgeStyle today).
If a new non-orthogonal style is added and the author forgets to set the flag, the edge will behave differently from its visual expectation.

Consider defaulting to false and letting the explicit opt-in convey intent:

- isOrthogonal: metadata.isOrthogonal ?? true,
+ if (!('isOrthogonal' in metadata)) {
+   metadata.isOrthogonal = false;
+ }
+ EdgeStyleRegistry.add(name, edgeStyle, metadata);

(or simply leave the property untouched).


101-105: unregisterAllEdgeStylesAndPerimeters name hides breaking change

The helper now delegates to two separate unregister functions.
To avoid surprises for existing callers, consider deprecating it instead of silently changing behaviour, or update the JSDoc to highlight that it is retained only for backward compatibility.

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

1497-1521: Typo & clarity in docstring

The sentence “Defines if the edge style is considered as orthogonal or not. @default false” misses a period and could be clearer:

“Indicates whether the edge style should be treated as orthogonal.
@default false”

Minor, but improves generated docs.

packages/core/__tests__/view/Graph.test.ts (1)

85-85: Remove redundant TODO comment

This TODO comment about already testing undefined values should be addressed since it creates unnecessary noise in the test file.

-      ['undefined', undefined], // TODO probably already tested above
+      ['undefined', undefined],
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a5d09dd and 8551814.

📒 Files selected for processing (40)
  • CHANGELOG.md (1 hunks)
  • packages/core/__tests__/util/BaseRegistry.test.ts (1 hunks)
  • packages/core/__tests__/view/Graph.test.ts (4 hunks)
  • packages/core/__tests__/view/GraphView.test.ts (6 hunks)
  • packages/core/__tests__/view/style/EdgeStyleRegistry.test.ts (1 hunks)
  • packages/core/src/index.ts (2 hunks)
  • packages/core/src/serialization/codecs/GraphViewCodec.ts (2 hunks)
  • packages/core/src/serialization/codecs/StylesheetCodec.ts (2 hunks)
  • packages/core/src/serialization/codecs/utils.ts (1 hunks)
  • packages/core/src/types.ts (5 hunks)
  • packages/core/src/util/BaseRegistry.ts (1 hunks)
  • packages/core/src/view/AbstractGraph.ts (7 hunks)
  • packages/core/src/view/GraphView.ts (4 hunks)
  • packages/core/src/view/style/StyleRegistry.ts (0 hunks)
  • packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1 hunks)
  • packages/core/src/view/style/edge/Elbow.ts (1 hunks)
  • packages/core/src/view/style/edge/EntityRelation.ts (1 hunks)
  • packages/core/src/view/style/edge/Loop.ts (1 hunks)
  • packages/core/src/view/style/edge/Manhattan.ts (1 hunks)
  • packages/core/src/view/style/edge/Orthogonal.ts (1 hunks)
  • packages/core/src/view/style/edge/Segment.ts (1 hunks)
  • packages/core/src/view/style/edge/SideToSide.ts (1 hunks)
  • packages/core/src/view/style/edge/TopToBottom.ts (1 hunks)
  • packages/core/src/view/style/marker/EdgeMarkerRegistry.ts (1 hunks)
  • packages/core/src/view/style/perimeter/EllipsePerimeter.ts (1 hunks)
  • packages/core/src/view/style/perimeter/HexagonPerimeter.ts (1 hunks)
  • packages/core/src/view/style/perimeter/PerimeterRegistry.ts (1 hunks)
  • packages/core/src/view/style/perimeter/RectanglePerimeter.ts (1 hunks)
  • packages/core/src/view/style/perimeter/RhombusPerimeter.ts (1 hunks)
  • packages/core/src/view/style/perimeter/TrianglePerimeter.ts (1 hunks)
  • packages/core/src/view/style/register.ts (4 hunks)
  • packages/html/stories/Wires.stories.js (2 hunks)
  • packages/js-example-selected-features/src/index.js (2 hunks)
  • packages/ts-example-selected-features/src/main.ts (2 hunks)
  • packages/ts-example-selected-features/vite.config.js (1 hunks)
  • packages/ts-example-without-defaults/vite.config.js (1 hunks)
  • packages/ts-example/vite.config.js (1 hunks)
  • packages/website/docs/usage/edge-styles.md (4 hunks)
  • packages/website/docs/usage/global-configuration.md (2 hunks)
  • packages/website/docs/usage/perimeters.md (3 hunks)
💤 Files with no reviewable changes (1)
  • packages/core/src/view/style/StyleRegistry.ts
🧰 Additional context used
🧠 Learnings (4)
packages/website/docs/usage/global-configuration.md (1)
Learnt from: tbouffard
PR: maxGraph/maxGraph#776
File: packages/core/src/view/Graph.ts:77-83
Timestamp: 2025-04-24T12:33:36.220Z
Learning: All register functions in maxGraph (`registerDefaultShapes`, `registerDefaultEdgeStyles`, `registerDefaultPerimeters`, and `registerDefaultEdgeMarkers`) have internal state flags to prevent duplicate registrations, making them inherently idempotent.
packages/website/docs/usage/perimeters.md (1)
Learnt from: tbouffard
PR: maxGraph/maxGraph#785
File: packages/core/src/view/style/register.ts:19-19
Timestamp: 2025-04-28T08:24:39.818Z
Learning: In the maxGraph project, the Perimeter namespace is defined in the './builtin-style-elements' file as a namespace export ('export * as Perimeter'), making this the correct import location for accessing the Perimeter namespace.
packages/js-example-selected-features/src/index.js (3)
Learnt from: tbouffard
PR: maxGraph/maxGraph#785
File: packages/core/src/view/style/register.ts:19-19
Timestamp: 2025-04-28T08:24:39.818Z
Learning: In the maxGraph project, the Perimeter namespace is defined in the 'builtin-style-elements.ts' file using the statement 'export * as Perimeter from './perimeter';'. To access the Perimeter namespace in other files, they must import from './builtin-style-elements' instead of directly from './perimeter', as part of the tree-shaking optimization.
Learnt from: tbouffard
PR: maxGraph/maxGraph#785
File: packages/core/src/view/style/register.ts:19-19
Timestamp: 2025-04-28T08:24:39.818Z
Learning: In the maxGraph project, the Perimeter namespace is defined in the './builtin-style-elements' file as a namespace export ('export * as Perimeter'), making this the correct import location for accessing the Perimeter namespace.
Learnt from: tbouffard
PR: maxGraph/maxGraph#776
File: packages/core/src/view/Graph.ts:77-83
Timestamp: 2025-04-24T12:33:36.220Z
Learning: All register functions in maxGraph (`registerDefaultShapes`, `registerDefaultEdgeStyles`, `registerDefaultPerimeters`, and `registerDefaultEdgeMarkers`) have internal state flags to prevent duplicate registrations, making them inherently idempotent.
packages/core/src/view/style/perimeter/PerimeterRegistry.ts (2)
Learnt from: tbouffard
PR: maxGraph/maxGraph#785
File: packages/core/src/view/style/register.ts:19-19
Timestamp: 2025-04-28T08:24:39.818Z
Learning: In the maxGraph project, the Perimeter namespace is defined in the 'builtin-style-elements.ts' file using the statement 'export * as Perimeter from './perimeter';'. To access the Perimeter namespace in other files, they must import from './builtin-style-elements' instead of directly from './perimeter', as part of the tree-shaking optimization.
Learnt from: tbouffard
PR: maxGraph/maxGraph#785
File: packages/core/src/view/style/register.ts:19-19
Timestamp: 2025-04-28T08:24:39.818Z
Learning: In the maxGraph project, the Perimeter namespace is defined in the './builtin-style-elements' file as a namespace export ('export * as Perimeter'), making this the correct import location for accessing the Perimeter namespace.
🧬 Code Graph Analysis (13)
packages/core/src/serialization/codecs/StylesheetCodec.ts (1)
packages/core/src/serialization/codecs/utils.ts (1)
  • getNameFromRegistries (25-33)
packages/core/src/serialization/codecs/GraphViewCodec.ts (1)
packages/core/src/serialization/codecs/utils.ts (1)
  • getNameFromRegistries (25-33)
packages/ts-example-selected-features/src/main.ts (3)
packages/core/src/index.ts (1)
  • PerimeterRegistry (207-207)
packages/core/src/view/style/perimeter/PerimeterRegistry.ts (1)
  • PerimeterRegistry (27-27)
packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1)
  • EdgeStyleRegistry (79-79)
packages/html/stories/Wires.stories.js (1)
packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1)
  • EdgeStyleRegistry (79-79)
packages/core/__tests__/util/BaseRegistry.test.ts (1)
packages/core/src/util/BaseRegistry.ts (1)
  • BaseRegistry (23-50)
packages/core/src/serialization/codecs/utils.ts (3)
packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1)
  • EdgeStyleRegistry (79-79)
packages/core/src/index.ts (1)
  • PerimeterRegistry (207-207)
packages/core/src/view/style/perimeter/PerimeterRegistry.ts (1)
  • PerimeterRegistry (27-27)
packages/js-example-selected-features/src/index.js (1)
packages/core/src/view/style/perimeter/PerimeterRegistry.ts (1)
  • PerimeterRegistry (27-27)
packages/core/__tests__/view/GraphView.test.ts (3)
packages/core/src/view/style/register.ts (2)
  • unregisterAllEdgeStyles (113-116)
  • unregisterAllPerimeters (125-128)
packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1)
  • EdgeStyleRegistry (79-79)
packages/core/src/view/style/perimeter/PerimeterRegistry.ts (1)
  • PerimeterRegistry (27-27)
packages/core/__tests__/view/style/EdgeStyleRegistry.test.ts (3)
packages/core/src/view/style/register.ts (1)
  • unregisterAllEdgeStyles (113-116)
packages/core/src/types.ts (1)
  • EdgeStyleFunction (1276-1282)
packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1)
  • EdgeStyleRegistry (79-79)
packages/core/src/view/GraphView.ts (3)
packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1)
  • EdgeStyleRegistry (79-79)
packages/core/src/index.ts (1)
  • PerimeterRegistry (207-207)
packages/core/src/view/style/perimeter/PerimeterRegistry.ts (1)
  • PerimeterRegistry (27-27)
packages/core/src/view/style/edge/EdgeStyleRegistry.ts (3)
packages/core/src/util/BaseRegistry.ts (1)
  • BaseRegistry (23-50)
packages/core/src/types.ts (3)
  • EdgeStyleFunction (1276-1282)
  • EdgeStyleHandlerKind (1497-1501)
  • EdgeStyleMetaData (1510-1521)
packages/core/src/internal/utils.ts (1)
  • isNullish (39-40)
packages/core/src/view/AbstractGraph.ts (2)
packages/core/src/types.ts (1)
  • EdgeStyleFunction (1276-1282)
packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1)
  • EdgeStyleRegistry (79-79)
packages/core/src/view/style/register.ts (3)
packages/core/src/types.ts (3)
  • EdgeStyleValue (1292-1300)
  • EdgeStyleFunction (1276-1282)
  • EdgeStyleMetaData (1510-1521)
packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1)
  • EdgeStyleRegistry (79-79)
packages/core/src/view/style/perimeter/PerimeterRegistry.ts (1)
  • PerimeterRegistry (27-27)
🪛 LanguageTool
packages/website/docs/usage/global-configuration.md

[uncategorized] ~55-~55: Loose punctuation mark.
Context: ...configurations. - EdgeStyleRegistry: edge styles (since 0.20.0, previously m...

(UNLIKELY_OPENING_PUNCTUATION)

🪛 markdownlint-cli2 (0.17.2)
packages/website/docs/usage/global-configuration.md

55-55: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


56-56: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


57-57: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


58-58: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build (windows-2022)
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build (macos-14)
🔇 Additional comments (78)
packages/ts-example/vite.config.js (1)

30-30: Approve updated chunkSizeWarningLimit value
The threshold has been incremented from 435 to 436 to match the current size of the @maxgraph/core chunk.

packages/ts-example-without-defaults/vite.config.js (1)

30-30: Approve lowered chunkSizeWarningLimit value
The warning limit has been decreased from 327 to 310 in line with the observed bundle size for @maxgraph/core.

packages/ts-example-selected-features/vite.config.js (1)

30-30: Approve adjusted chunkSizeWarningLimit value
The limit reduction from 378 to 370 aligns with the updated build output size for the core chunk.

packages/core/src/view/style/perimeter/EllipsePerimeter.ts (1)

25-25: Confirm JSDoc update to PerimeterRegistry.

The documentation line is correctly updated to reference PerimeterRegistry instead of the removed StyleRegistry, aligning with the new registry architecture.

packages/core/src/view/style/perimeter/RectanglePerimeter.ts (1)

27-27: Approve JSDoc correction to PerimeterRegistry.

The perimeter registration comment now accurately points to PerimeterRegistry, matching the PR’s registry refactor.

packages/core/src/view/style/perimeter/HexagonPerimeter.ts (1)

26-26: Validate JSDoc reference update.

The comment for HexagonPerimeter is now properly linked to PerimeterRegistry, consistent with the architectural change.

packages/core/src/view/style/perimeter/TrianglePerimeter.ts (1)

26-26: Approve updated JSDoc to PerimeterRegistry.

The triangle perimeter’s registration comment correctly references PerimeterRegistry following the removal of StyleRegistry.

packages/core/src/view/style/perimeter/RhombusPerimeter.ts (1)

26-26: Confirm JSDoc update for PerimeterRegistry.

The rhombus perimeter comment is now aligned with the new PerimeterRegistry API, as intended by the PR.

packages/core/src/serialization/codecs/GraphViewCodec.ts (1)

18-18: Import updated for multi-registry lookup
Replacing StyleRegistry with the new getNameFromRegistries utility correctly aligns this codec with the dedicated EdgeStyleRegistry and PerimeterRegistry approach.

CHANGELOG.md (1)

33-34: Changelog entry reflects registry refactor
The removal of StyleRegistry and introduction of EdgeStyleRegistry/PerimeterRegistry is clearly documented under breaking changes.

packages/core/src/serialization/codecs/StylesheetCodec.ts (2)

18-18: Import updated for new registry architecture.

The import has been updated to use getNameFromRegistries utility function instead of directly importing StyleRegistry, aligning with the new registry architecture.


88-88: Correctly migrated to use the new registry lookup utility.

This change properly replaces the direct reference to StyleRegistry.getName(value) with the new getNameFromRegistries(value) utility function which checks multiple registries (EdgeStyleRegistry and PerimeterRegistry).

This approach maintains the same functionality while enabling tree-shaking benefits described in the PR objectives.

packages/core/src/view/style/edge/EntityRelation.ts (1)

38-42: Documentation updated for new EdgeStyleRegistry structure.

The documentation has been correctly updated to reference EdgeStyleRegistry instead of StyleRegistry and now includes important metadata requirements for manual registration.

Including the required metadata (handlerKind: 'default' and isOrthogonal: true) is essential guidance for developers who might manually register this edge style.

packages/js-example-selected-features/src/index.js (2)

30-30: Updated import to use specialized PerimeterRegistry.

Correctly replaced StyleRegistry import with the new PerimeterRegistry import.


42-42: Updated registration to use PerimeterRegistry.add.

The registration method has been properly updated from StyleRegistry.putValue to PerimeterRegistry.add, maintaining the same functionality while using the new specialized registry API.

This change is consistent with the PR's goal of replacing the general StyleRegistry with specialized registries for better tree-shaking.

packages/core/src/view/style/edge/Loop.ts (1)

28-32: Documentation updated for new EdgeStyleRegistry structure.

The JSDoc comment has been correctly updated to reference EdgeStyleRegistry instead of StyleRegistry and now includes the specific metadata requirements for manual registration.

Specifying handlerKind: 'elbow' and isOrthogonal: false as required metadata provides valuable guidance for developers who might manually register this edge style.

packages/core/src/view/style/edge/Manhattan.ts (1)

31-35: Documentation updated correctly to reflect new registry architecture.

The documentation has been appropriately updated to reference the new EdgeStyleRegistry instead of the removed StyleRegistry, along with clear instructions about required metadata when manually registering this EdgeStyle. This change aligns with the architectural improvements for tree-shaking.

packages/html/stories/Wires.stories.js (2)

70-70: Import statement correctly updated for new registry architecture.

The import statement has been properly updated to use EdgeStyleRegistry instead of the removed StyleRegistry.


701-701: Registration method correctly updated to use new EdgeStyleRegistry.

The code now properly uses EdgeStyleRegistry.add() instead of StyleRegistry.putValue(), which aligns with the architectural changes to improve tree-shaking.

However, based on the changes in other files, you should consider adding required metadata for this EdgeStyle:

-EdgeStyleRegistry.add('wireEdgeStyle', WireConnector);
+EdgeStyleRegistry.add('wireEdgeStyle', WireConnector, {
+  handlerKind: 'segment', // Or appropriate handler kind
+  isOrthogonal: true      // If this is an orthogonal edge style
+});
packages/core/src/view/style/edge/SideToSide.ts (1)

28-32: Documentation updated correctly to reflect new registry architecture.

The documentation has been appropriately updated to reference the new EdgeStyleRegistry instead of the removed StyleRegistry, along with clear instructions about required metadata when manually registering this EdgeStyle. This change supports the new architecture for better tree-shaking.

packages/core/src/view/style/edge/TopToBottom.ts (1)

28-32: Documentation updated correctly to reflect new registry architecture.

The documentation has been appropriately updated to reference the new EdgeStyleRegistry instead of the removed StyleRegistry, along with clear instructions about required metadata when manually registering this EdgeStyle. This change aligns with the architectural improvements for tree-shaking.

packages/ts-example-selected-features/src/main.ts (2)

26-27: Import updates correctly refer to the new registries

The imports have been updated to use the new dedicated registries (EdgeStyleRegistry and PerimeterRegistry) instead of the now removed StyleRegistry, aligning with the architectural changes in the project.

Also applies to: 33-34


49-54: Registration API properly updated with metadata support

The perimeter and edge style registrations have been properly migrated to use the new dedicated registry APIs. The edge style registration now includes the appropriate metadata (handlerKind and isOrthogonal), which enables improved tree-shaking as mentioned in the PR objectives.

The metadata specified here is particularly important for the orthogonalEdgeStyle, as it correctly identifies it as an orthogonal edge style and specifies the segment handler kind, which will be used by the framework to correctly process this edge style.

packages/core/src/view/style/perimeter/PerimeterRegistry.ts (3)

17-19: Appropriate imports for the new registry

The imports correctly reference the BaseRegistry class and PerimeterFunction type that are needed for the implementation.


20-26: Well-documented registry with proper JSDoc

The documentation clearly explains the purpose of the registry and includes appropriate JSDoc tags for categorization and versioning.


27-27: Simple and effective implementation of the registry

The implementation correctly instantiates a BaseRegistry parametrized with PerimeterFunction, which aligns with the PR's goal of creating a dedicated registry for perimeter functions.

Based on the retrieved learnings, this implementation properly supports the way Perimeter functions are managed in the codebase, helping to enable tree-shaking as mentioned in the PR objectives.

packages/website/docs/usage/perimeters.md (4)

23-25: Documentation updated for new registry

The documentation correctly mentions that perimeters are now registered in the PerimeterRegistry instead of the previous registry.


27-31: Clear notice about breaking change

The added information box clearly communicates the breaking change to users, specifying that the PerimeterRegistry is new in version 0.20.0 and replaces the previous StyleRegistry. This helps users understand and adapt to the architectural changes.


111-116: Updated string-based perimeter registration explanation

The documentation correctly explains the updated registration mechanism for string-based perimeter references, now using PerimeterRegistry instead of the previous registry.


151-154: Custom perimeter registration example updated

The example for registering custom perimeters has been properly updated to use PerimeterRegistry.add() instead of the previous method, ensuring users understand how to register custom perimeters with the new API.

packages/core/__tests__/view/GraphView.test.ts (6)

22-28: Updated imports for new registries and unregister functions

The imports have been correctly updated to include the new dedicated registries (EdgeStyleRegistry and PerimeterRegistry) and their respective unregister functions, replacing the previous imports.


58-64: Updated edge style test cleanup

The test setup and cleanup now correctly use unregisterAllEdgeStyles() instead of the previous method, ensuring test isolation is maintained.


88-95: Updated edge style registration in tests

The test now correctly uses EdgeStyleRegistry.add() to register edge styles, which verifies that the new API functions properly within the application.


97-107: Edge style test with noEdgeStyle properly updated

The test for the noEdgeStyle property correctly uses the new registry API while maintaining the same functionality check.


119-126: Updated perimeter test cleanup

The perimeter test setup and cleanup now correctly use unregisterAllPerimeters() instead of the previous method, ensuring test isolation.


140-147: Updated perimeter registration in tests

The test now correctly uses PerimeterRegistry.add() to register perimeter functions, which verifies that the new API functions properly.

packages/core/__tests__/util/BaseRegistry.test.ts (5)

1-15: License header looks good.

The license header follows the standard Apache 2.0 format and properly attributes copyright to The maxGraph project Contributors.


17-18: Imports are correctly structured.

The test imports the necessary Jest globals and the BaseRegistry class being tested. The import path is properly structured to access the BaseRegistry from the src directory.


20-29: Comprehensive registration test looks good.

This test effectively verifies:

  1. Adding an object to the registry
  2. Retrieving a registered object by name
  3. Handling unknown names by returning null
  4. Handling edge cases (null, undefined) correctly

The test provides good coverage of the BaseRegistry's basic functionality.


31-39: Clear functionality test is well implemented.

The test properly verifies that the clear method removes all registry entries by:

  1. First adding an entry and confirming it exists
  2. Calling clear() method
  3. Verifying the entry no longer exists

This test is essential as the clear function is used by the unregister functions mentioned in the PR objectives.


41-59: getName tests are thorough and well-structured.

The tests properly verify the getName functionality in two scenarios:

  1. When the registry is empty - confirming it returns null for any object
  2. When the registry contains entries - confirming it returns the correct name for a registered object

The structure using a describe block for grouping related tests follows best practices. This functionality is critical for the getNameFromRegistries utility that leverages this method.

packages/core/src/serialization/codecs/utils.ts (3)

17-18: Correct imports for the new registry structure.

The file correctly imports the new dedicated registries that replace the former StyleRegistry. This aligns with the PR objective of introducing separate registries for edge styles and perimeters.


20-20: Good approach for registry collection.

Storing the registries in an array enables a clean iteration pattern in the utility function. This makes the code more maintainable if additional registries need to be added in the future.


22-33: Well-implemented utility function for cross-registry lookups.

The getNameFromRegistries function:

  1. Is correctly versioned with @since 0.20.0 to indicate it's part of the breaking change
  2. Efficiently iterates through each registry to find a matching name
  3. Returns early when a match is found for better performance
  4. Falls back to null if no name is found across all registries

This function is essential for code that previously relied on StyleRegistry.getName() to find style names for serialization purposes.

packages/website/docs/usage/global-configuration.md (1)

76-78: Documentation correctly updated for new unregister functions.

The documentation now properly lists:

  1. unregisterAllEdgeStyles() - new in 0.20.0
  2. unregisterAllPerimeters() - new in 0.20.0
  3. Retains the previous unregisterAllEdgeStylesAndPerimeters() for backwards compatibility

This helps users understand the new, more granular approach to registry management introduced in this PR.

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

45-46: Imports correctly updated to use the new registry structure.

The imports properly reference the new dedicated registries:

  1. EdgeStyleRegistry for edge styles
  2. PerimeterRegistry for perimeters

This is a key part of implementing the registry split mentioned in the PR objectives.


138-140: Documentation comment correctly updated for allowEval property.

The comment now accurately reflects that the new EdgeStyleRegistry and PerimeterRegistry are used when resolving style values, replacing the previous reference to StyleRegistry. This ensures the documentation stays in sync with the implementation changes.


1327-1336: Edge style resolution updated to use EdgeStyleRegistry.

The code correctly:

  1. Replaces the previous StyleRegistry lookup with EdgeStyleRegistry.get()
  2. Maintains the fallback to eval when necessary
  3. Preserves the same behavior while using the new registry structure

This change implements a key part of the PR objective to improve tree-shaking by removing hard-coded EdgeStyle references.


1596-1602: Perimeter function resolution updated to use PerimeterRegistry.

The code correctly:

  1. Replaces the previous StyleRegistry lookup with PerimeterRegistry.get()
  2. Maintains the fallback to eval when necessary
  3. Preserves the same behavior while using the new registry structure

This change completes the implementation of the registry split mentioned in the PR objectives.

packages/core/__tests__/view/style/EdgeStyleRegistry.test.ts (7)

17-24: Good use of imports and test setup

The imports correctly include all the necessary components from the core library, including EdgeStyle, EdgeStyleFunction, EdgeStyleRegistry, and unregisterAllEdgeStyles. This sets up the tests for the new registry properly.


25-33: Excellent test isolation practice

The warning comment and use of beforeEach and afterAll hooks to clear the registry state prevents side effects between tests and other test suites. This is critical when testing components that rely on global state.


35-38: Good test helper setup

The custom edge style function is properly defined with the correct type signature (EdgeStyleFunction), and the empty implementation is sufficient for testing purposes since we're only testing registration functionality.


39-48: Complete metadata registration test

This test properly verifies that edge styles can be registered with metadata and that all metadata properties (isOrthogonal and handlerKind) are correctly retrieved. The use of direct comparisons and boolean assertions is appropriate.


50-56: Good default values test

This test verifies that registering an edge style without metadata results in correct default values (handlerKind is 'default' and isOrthogonal is false). This ensures the registry behaves predictably when metadata is omitted.


58-71: Thorough clear functionality test

The test properly verifies that the clear method removes all registered styles and resets their metadata to default values. This is important for ensuring that the registry can be properly reset between tests or during application lifecycle.


73-88: Comprehensive getName tests

The tests for the getName method cover both the case where no elements are registered and where multiple elements are registered. The tests properly verify that the correct name is returned for a registered function and that null is returned for unregistered functions or null input.

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

184-184: Properly exposing BaseRegistry in public API

Good addition of the BaseRegistry export which makes the generic registry functionality available to consumers.


205-205: Correctly exposing EdgeStyleRegistry

The export for edge style registry functionality is properly added, making the new registry available to consumers.


207-207: Properly exposing PerimeterRegistry

The named export for PerimeterRegistry correctly replaces the previous StyleRegistry, completing the transition to dedicated registries.

packages/website/docs/usage/edge-styles.md (6)

21-21: Updated documentation to reflect new registry

The documentation correctly reflects that EdgeStyles are now registered in the EdgeStyleRegistry instead of the previous StyleRegistry.


25-29: Clear version change information

Good addition of an info box explaining the introduction of EdgeStyleRegistry in version 0.20.0 and the removal of StyleRegistry. This helps users understand the breaking changes.


39-39: Updated example to reference EdgeStyleRegistry

The example now correctly references the new EdgeStyleRegistry for the built-in EdgeStyle registration.


51-51: Consistent registry naming

The documentation for configuring default edge styles has been updated to reference the new EdgeStyleRegistry, maintaining consistency throughout the document.


83-90: Clear metadata registration example

The example for registering a custom edge style now includes the important metadata parameters (handlerKind and isOrthogonal). This is crucial for ensuring that custom edge styles work correctly with the framework.


92-95: Important warning about metadata registration

Excellent addition of a warning about the importance of registering EdgeStyles with correct metadata. This will help prevent subtle bugs when users create custom edge styles.

packages/core/src/util/BaseRegistry.ts (5)

17-22: Well-documented class with proper JSDoc annotations

The class includes comprehensive JSDoc comments with appropriate category tags and version information, making it clear that this is a new addition in version 0.20.0.


23-25: Good use of generics for type safety

The BaseRegistry<V> class properly uses TypeScript generics to provide type safety for the values stored in the registry. The protected map is a good implementation choice for the storage.


26-33: Simple and effective add/get methods

The add and get methods are straightforward and handle null/undefined inputs gracefully. The null fallback in the get method is a good defensive programming practice.


34-41: Efficient getName implementation

The getName method correctly handles the lookup of a style's name by iterating through entries. The early return when a match is found is efficient, and returning null for unregistered values is consistent with the get method.


43-49: Clear warning about clear method usage

The clear method is properly documented with a warning that it should not be called directly, encouraging users to use the global unregister functions instead. This helps maintain the integrity of the registry state.

packages/core/__tests__/view/Graph.test.ts (8)

17-34: Good addition of registry-related imports

The additional imports for registerDefaultEdgeStyles and unregisterAllEdgeStyles align well with the PR's objective of introducing dedicated registries. These functions are essential for the test setup to properly isolate and test behavior with and without registered edge styles.


58-91: Well-structured test isolation for registered styles

The addition of this nested describe block with proper setup and teardown is excellent. This clearly separates tests for when default edge styles are registered, ensuring clean test isolation. The beforeEach/afterAll pattern ensures each test runs with a clean state.


93-112: Clear test organization for unregistered styles

Good refactoring of these tests to explicitly indicate they're for the case when default built-in styles are NOT registered. This complements the earlier describe block and makes the test scenarios much clearer.


115-126: Good extraction of helper functions

The refactoring of createCellState to an arrow function and addition of the createCellStateOfEdge helper function improves code readability and reduces duplication in the tests. This is a good pattern for test utilities.


129-172: Comprehensive testing of handler creation

The new test cases effectively verify that the createEdgeHandler method properly delegates to the registry to determine which handler type to use based on the registered style metadata. The tests are well-structured and cover all expected handler types for different edge styles.


186-187: Clear test naming for unregistered styles scenario

Good modification of the test description to explicitly indicate it's testing the scenario when default built-in styles are NOT registered. This naming helps clearly differentiate between the two test scenarios.


190-190: Good use of utility function for precise assertion

Using the expectExactInstanceOfEdgeHandler utility function here provides a more precise assertion than just checking for instanceof EdgeHandler, as it explicitly verifies the handler is not a subclass.


209-213: Excellent utility function for precise type assertions

The addition of expectExactInstanceOfEdgeHandler is a great improvement. It not only checks that the handler is an instance of EdgeHandler, but also verifies it's not a subclass, which is crucial for these tests. This kind of utility function enhances test precision and readability.

tbouffard added 5 commits May 5, 2025 19:41
No longer tries to do it with object in GraphViewCodec.
The related registries only hold function.
In addition, the logic was wrong. It should have been a OR instead of a AND when checking for 'function' and 'object'.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
packages/core/src/internal/BaseRegistry.ts (2)

31-33: Consider refactoring to avoid non-null assertion

The get method uses a non-null assertion operator (!) on name which could hide potential issues. While the nullish coalescing operator handles the case afterward, it would be clearer to check if name is a valid string before trying to get it from the map.

  get(name: string | null | undefined): V | null {
-   return this.values.get(name!) ?? null;
+   if (name === null || name === undefined) {
+     return null;
+   }
+   return this.values.get(name) ?? null;
  }

35-42: Consider performance implications for large registries

The getName method performs a linear search through all entries. This implementation is straightforward and works well for small registries, but could become a performance bottleneck if the registry grows large.

For the current use case of style registries, this is likely acceptable since the number of registered styles is typically small. If performance becomes an issue, consider maintaining a reverse lookup map.

packages/core/__tests__/internal/BaseRegistry.test.ts (3)

2-2: Update the copyright year to 2024

The copyright year is set to 2025, which is in the future. This should be updated to the current year (2024) or a range (e.g., "2023-2024") if the project started earlier.

-Copyright 2025-present The maxGraph project Contributors
+Copyright 2024-present The maxGraph project Contributors

21-21: Consider adding type parameter for better type safety

The BaseRegistry is instantiated without specifying the generic type parameter. While TypeScript can infer the type in this case, explicitly specifying it would improve code clarity and type safety.

-  const baseRegistry = new BaseRegistry();
+  const baseRegistry = new BaseRegistry<Record<string, string>>();

1-60: Consider adding tests for registry entry overrides

The current tests don't verify what happens when you register multiple values with the same key. According to the BaseRegistry implementation, the latest registration should override previous ones, but this behavior isn't tested.

test('registration override', () => {
  const baseRegistry = new BaseRegistry<Record<string, string>>();
  const object1 = { property: 'value1' };
  const object2 = { property: 'value2' };
  
  baseRegistry.add('name', object1);
  expect(baseRegistry.get('name')).toBe(object1);
  
  baseRegistry.add('name', object2);
  expect(baseRegistry.get('name')).toBe(object2);
  expect(baseRegistry.get('name')).not.toBe(object1);
});
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2279657 and 977f5e8.

📒 Files selected for processing (6)
  • packages/core/__tests__/internal/BaseRegistry.test.ts (1 hunks)
  • packages/core/src/index.ts (1 hunks)
  • packages/core/src/internal/BaseRegistry.ts (1 hunks)
  • packages/core/src/types.ts (5 hunks)
  • packages/core/src/view/style/edge/EdgeStyleRegistry.ts (1 hunks)
  • packages/core/src/view/style/perimeter/PerimeterRegistry.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • packages/core/src/view/style/edge/EdgeStyleRegistry.ts
  • packages/core/src/view/style/perimeter/PerimeterRegistry.ts
  • packages/core/src/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/types.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/core/__tests__/internal/BaseRegistry.test.ts (1)
packages/core/src/internal/BaseRegistry.ts (1)
  • BaseRegistry (24-47)
packages/core/src/internal/BaseRegistry.ts (1)
packages/core/src/types.ts (1)
  • Registry (1496-1508)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: build (macos-14)
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build
  • GitHub Check: build (windows-2022)
🔇 Additional comments (4)
packages/core/src/internal/BaseRegistry.ts (1)

24-47: Good implementation of base registry

This foundational BaseRegistry class provides a simple yet effective implementation of the Registry interface. The protected values map enables subclasses to extend functionality while maintaining encapsulation.

The class provides all the necessary operations (add, get, getName, clear) with appropriate null handling. The @private and version annotations properly document that this is an internal implementation detail.

packages/core/__tests__/internal/BaseRegistry.test.ts (3)

20-29: LGTM! Good test coverage for basic registry functionality.

This test thoroughly verifies the core registration functionality, including edge cases for non-existent keys, null, and undefined inputs. The test ensures the registry correctly returns the registered object for valid keys and null for invalid ones.


31-39: LGTM! Clear test verifies registry reset functionality.

This test properly verifies that the clear method removes all registered entries from the registry.


41-59: LGTM! Comprehensive tests for getName functionality.

These tests thoroughly verify the getName method in both scenarios - when the registry is empty and when it contains multiple entries. Good job testing the null input case in both scenarios.

@sonarqubecloud
Copy link

sonarqubecloud bot commented May 6, 2025

@tbouffard tbouffard merged commit 9607431 into main May 6, 2025
7 checks passed
@tbouffard tbouffard deleted the feat/introduce_EdgeStyleRegistry branch May 6, 2025 08:16
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.

Make Graph.createEdgeHandler and Graph.isOrthogonal configurable and independent from EdgeStyle implementation

1 participant