Repository: maxGraph/maxGraph
Pull request #291 (2023-12-18 01:19:54)

chore(deps-gha): bump actions/upload-artifact from 3 to 4
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<h2>What's Changed</h2>
<p>The release of upload-artifact@v4 and download-artifact@v4 are major changes to the backend architecture of Artifacts. They have numerous performance and behavioral improvements.</p>
<p>For more information, see the <a href="https://github.com/actions/toolkit/tree/main/packages/artifact"><code>@​actions/artifact</code></a> documentation.</p>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/vmjoseph"><code>@​vmjoseph</code></a> made their first contribution in <a href="https://redirect.github.com/actions/upload-artifact/pull/464">actions/upload-artifact#464</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/upload-artifact/compare/v3...v4.0.0">https://github.com/actions/upload-artifact/compare/v3...v4.0.0</a></p>
<h2>v3.1.3</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(github): remove trailing whitespaces by <a href="https://github.com/ljmf00"><code>@​ljmf00</code></a> in <a href="https://redirect.github.com/actions/upload-artifact/pull/313">actions/upload-artifact#313</a></li>
<li>Bump <code>@​actions/artifact</code> version to v1.1.2 by <a href="https://github.com/bethanyj28"><code>@​bethanyj28</code></a> in <a href="https://redirect.github.com/actions/upload-artifact/pull/436">actions/upload-artifact#436</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/upload-artifact/compare/v3...v3.1.3">https://github.com/actions/upload-artifact/compare/v3...v3.1.3</a></p>
<h2>v3.1.2</h2>
<ul>
<li>Update all <code>@actions/*</code> NPM packages to their latest versions- <a href="https://redirect.github.com/actions/upload-artifact/issues/374">#374</a></li>
<li>Update all dev dependencies to their most recent versions - <a href="https://redirect.github.com/actions/upload-artifact/issues/375">#375</a></li>
</ul>
<h2>v3.1.1</h2>
<ul>
<li>Update actions/core package to latest version to remove <code>set-output</code> deprecation warning <a href="https://redirect.github.com/actions/upload-artifact/issues/351">#351</a></li>
</ul>
<h2>v3.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/artifact</code> to v1.1.0 (<a href="https://redirect.github.com/actions/upload-artifact/pull/327">actions/upload-artifact#327</a>)
<ul>
<li>Adds checksum headers on artifact upload (<a href="https://redirect.github.com/actions/toolkit/pull/1095">actions/toolkit#1095</a>) (<a href="https://redirect.github.com/actions/toolkit/pull/1063">actions/toolkit#1063</a>)</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/actions/upload-artifact/commit/c7d193f32edcb7bfad88892161225aeda64e9392"><code>c7d193f</code></a> Merge pull request <a href="https://redirect.github.com/actions/upload-artifact/issues/466">#466</a> from actions/v4-beta</li>
<li><a href="https://github.com/actions/upload-artifact/commit/13131bb095770b4070a7477c3cd2d96e1c16d9f4"><code>13131bb</code></a> licensed cache</li>
<li><a href="https://github.com/actions/upload-artifact/commit/4a6c273b9834f66a1d05c170dc3f80f9cdb9def1"><code>4a6c273</code></a> Merge branch 'main' into v4-beta</li>
<li><a href="https://github.com/actions/upload-artifact/commit/f391bb91a3d3118aeca171c365bb319ece276b37"><code>f391bb9</code></a> Merge pull request <a href="https://redirect.github.com/actions/upload-artifact/issues/465">#465</a> from actions/robherley/v4-documentation</li>
<li><a href="https://github.com/actions/upload-artifact/commit/9653d03c4b74c32144e02dae644fea70e079d4b3"><code>9653d03</code></a> Apply suggestions from code review</li>
<li><a href="https://github.com/actions/upload-artifact/commit/875b63076402f25ef9d52c294c86ba4f97810575"><code>875b630</code></a> add limitations section</li>
<li><a href="https://github.com/actions/upload-artifact/commit/ecb21463e93740a6be75c3116242169bfdbcb15a"><code>ecb2146</code></a> add compression example</li>
<li><a href="https://github.com/actions/upload-artifact/commit/5e7604f84a055838f64ed68bb9904751523081ae"><code>5e7604f</code></a> trim some repeated info</li>
<li><a href="https://github.com/actions/upload-artifact/commit/d6437d07581fe318a364512e6cf6b1dca6b4f92c"><code>d6437d0</code></a> naming</li>
<li><a href="https://github.com/actions/upload-artifact/commit/1b561557037b4957d7d184e9aac02bec86c771eb"><code>1b56155</code></a> s/v4-beta/v4/g</li>
<li>Additional commits viewable in <a href="https://github.com/actions/upload-artifact/compare/v3...v4">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=3&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9dd2541b7..be007d608 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -53,9 +53,9 @@ jobs:
       - name: Build Storybook mini-site
         run: npm run build -w packages/html
       - name: Upload all examples as artifact
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v4
         with:
-          name: bundles-test-results-${{github.sha}}
+          name: bundles-test-results-${{runner.os}}-${{github.sha}}
           path: |
             packages/html/dist/
             packages/ts-example/dist/
diff --git a/.github/workflows/generate-website.yml b/.github/workflows/generate-website.yml
index 82e771632..3e70920ec 100644
--- a/.github/workflows/generate-website.yml
+++ b/.github/workflows/generate-website.yml
@@ -27,7 +27,7 @@ jobs:
       - name: Build website
         run: npm run build -w packages/website
       - name: Upload website artifact
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v4
         with:
           name: website-${{github.sha}}
           path: |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b884f4b5..1ac0c12ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,8 @@ You can use one of the following functions to register codecs:
   - `registerCoreCodecs`
   - `registerEditorCodecs`
 
+To serialize the `maxGraph` model, you can use the `ModelXmlSerializer` class, which registers codecs under the hood.
+
 ## 0.5.0
 
 Release date: `2023-12-07`
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 33ee0a5cd..1a8b55432 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -114,6 +114,7 @@ export { default as SwimlaneOrdering } from './view/layout/hierarchical/Swimlane
 export { default as Codec } from './serialization/Codec';
 export { default as CodecRegistry } from './serialization/CodecRegistry';
 export { default as ObjectCodec } from './serialization/ObjectCodec';
+export * from './serialization/ModelXmlSerializer';
 export * from './serialization/codecs';
 export * from './serialization/register';
 
diff --git a/packages/core/src/serialization/ModelXmlSerializer.ts b/packages/core/src/serialization/ModelXmlSerializer.ts
new file mode 100644
index 000000000..770a1b9ec
--- /dev/null
+++ b/packages/core/src/serialization/ModelXmlSerializer.ts
@@ -0,0 +1,73 @@
+/*
+Copyright 2023-present The maxGraph project Contributors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import { registerCoreCodecs } from './register';
+import { getPrettyXml, parseXml } from '../util/xmlUtils';
+import { Codec } from '../index';
+import type GraphDataModel from '../view/GraphDataModel';
+
+/**
+ * Export options of {@link ModelXmlSerializer}.
+ *
+ * **WARN**: this is an experimental feature that is subject to change.
+ *
+ * @alpha
+ * @experimental
+ * @since 0.6.0
+ */
+export type ModelExportOptions = {
+  /**
+   * If `true`, prettify the exported xml.
+   * @default true
+   */
+  pretty?: boolean;
+};
+
+/**
+ * Convenient utility class using {@link Codec} to manage maxGraph model import and export.
+ *
+ * **WARN**: this is an experimental feature that is subject to change (class and method names).
+ *
+ * @alpha
+ * @experimental
+ * @since 0.6.0
+ */
+// Include 'XML' in the class name as there were past discussions about supporting other format like JSON for example
+// See https://github.com/maxGraph/maxGraph/discussions/60 for more details.
+export class ModelXmlSerializer {
+  constructor(private dataModel: GraphDataModel) {
+    this.registerCodecs();
+  }
+
+  import(xml: string): void {
+    const doc = parseXml(xml);
+    new Codec(doc).decode(doc.documentElement, this.dataModel);
+  }
+
+  export(options?: ModelExportOptions): string {
+    const encodedNode = new Codec().encode(this.dataModel);
+    return options?.pretty ?? true
+      ? getPrettyXml(encodedNode)
+      : getPrettyXml(encodedNode, '', '', '');
+  }
+
+  /**
+   * Hook for replacing codecs registered by default (core codecs).
+   */
+  protected registerCodecs(): void {
+    registerCoreCodecs();
+  }
+}
diff --git a/packages/website/docs/usage/migrate-from-mxgraph.md b/packages/website/docs/usage/migrate-from-mxgraph.md
index a33253776..3e4907397 100644
--- a/packages/website/docs/usage/migrate-from-mxgraph.md
+++ b/packages/website/docs/usage/migrate-from-mxgraph.md
@@ -541,7 +541,9 @@ This is currently not supported in maxGraph: https://github.com/maxGraph/maxGrap
 
 From version 0.6.0 of `maxGraph`, codecs supplied by maxGraph are no longer registered by default, they ** MUST** be registered before performing an `encode` or `decode`
 
-For example, you can use the `registerCoreCodecs` function (or other related functions) to register codecs.
+For example:
+- You can use the `registerCoreCodecs` function (or other related functions) to register codecs.
+- To serialize the `maxGraph` model, you can use the `ModelXmlSerializer` class, which registers codecs under the hood.
 
 :::
 


Test patch:
diff --git a/packages/core/__tests__/serialization/serialization.xml.test.ts b/packages/core/__tests__/serialization/serialization.xml.test.ts
index 13b26c9d2..edaec3866 100644
--- a/packages/core/__tests__/serialization/serialization.xml.test.ts
+++ b/packages/core/__tests__/serialization/serialization.xml.test.ts
@@ -16,47 +16,7 @@ limitations under the License.
 
 import { describe, expect, test } from '@jest/globals';
 import { createGraphWithoutContainer } from '../utils';
-import {
-  Cell,
-  Codec,
-  Geometry,
-  GraphDataModel,
-  Point,
-  registerCoreCodecs,
-} from '../../src';
-import { getPrettyXml, parseXml } from '../../src/util/xmlUtils';
-
-type ModelExportOptions = {
-  /**
-   * @default true
-   */
-  pretty?: boolean;
-};
-
-/**
- * Convenient utility class using {@link Codec} to manage maxGraph model import and export.
- *
- * @internal
- * @alpha subject to change (class and method names)
- */
-class ModelXmlSerializer {
-  // Include 'XML' in the class name as there were past discussions about supporting other format (JSON for example {@link https://github.com/maxGraph/maxGraph/discussions/60}).
-  constructor(private dataModel: GraphDataModel) {
-    registerCoreCodecs();
-  }
-
-  import(xml: string): void {
-    const doc = parseXml(xml);
-    new Codec(doc).decode(doc.documentElement, this.dataModel);
-  }
-
-  export(options?: ModelExportOptions): string {
-    const encodedNode = new Codec().encode(this.dataModel);
-    return options?.pretty ?? true
-      ? getPrettyXml(encodedNode)
-      : getPrettyXml(encodedNode, '', '', '');
-  }
-}
+import { Cell, Geometry, GraphDataModel, ModelXmlSerializer, Point } from '../../src';
 
 // inspired by VertexMixin.createVertex
 const newVertex = (id: string, value: string) => {