@qubit-ltd/common-decorator 3.8.10 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,7 +24,7 @@
24
24
  <label for="nav-trigger" class="overlay"></label>
25
25
 
26
26
  <nav>
27
- <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="DefaultAssignmentOptions.html">DefaultAssignmentOptions</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="DefaultOptions.html">DefaultOptions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="DefaultOptions.html#.get">get</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="DefaultOptions.html#.merge">merge</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="DefaultOptions.html#.reset">reset</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="DefaultOptions.html#.set">set</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="DefaultToJsonOptions.html">DefaultToJsonOptions</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Page.html">Page</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Page.html#assign">assign</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Page.html#.getFrom">getFrom</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Page.html#.newEmpty">newEmpty</a></span></li><li class="nav-heading">Namespaces</li><li class="nav-heading"><span class="nav-item-type type-namespace">N</span><span class="nav-item-name"><a href="Enum.html">Enum</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.has">Class.has</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.hasCode">Class.hasCode</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.hasName">Class.hasName</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.hasValue">Class.hasValue</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.of">Class.of</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.ofCode">Class.ofCode</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.ofName">Class.ofName</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.ofValue">Class.ofValue</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.values">Class.values</a></span></li><li class="nav-heading"><span class="nav-item-type type-namespace">N</span><span class="nav-item-name"><a href="Model.html">Model</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#assign">assign</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#clear">clear</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#equals">equals</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#generateId">generateId</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#isEmpty">isEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#normalize">normalize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#normalizeField">normalizeField</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#toJsonString">toJsonString</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#validate">validate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#validateField">validateField</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.create">Class.create</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.createArray">Class.createArray</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.createPage">Class.createPage</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.isNullishOrEmpty">Class.isNullishOrEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.parseJsonString">Class.parseJsonString</a></span></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#ElementType">ElementType</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Enumerable">Enumerable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Label">Label</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#NameField">NameField</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#NonEmpty">NonEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#NonEnumerable">NonEnumerable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Normalizable">Normalizable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Nullable">Nullable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Payload">Payload</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Readonly">Readonly</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Timeout">Timeout</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Type">Type</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Validatable">Validatable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#assign">assign</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#create">create</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createArray">createArray</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createPage">createPage</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#defaultNormalizer">defaultNormalizer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#defaultValidator">defaultValidator</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#enumNormalizer">enumNormalizer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isEnumClass">isEnumClass</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isEnumerator">isEnumerator</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isValidPageSource">isValidPageSource</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#normalize">normalize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#stringifyId">stringifyId</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#toJsonString">toJsonString</a></span></li>
27
+ <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="DefaultAssignmentOptions.html">DefaultAssignmentOptions</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="DefaultOptions.html">DefaultOptions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="DefaultOptions.html#.get">get</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="DefaultOptions.html#.merge">merge</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="DefaultOptions.html#.reset">reset</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="DefaultOptions.html#.set">set</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="DefaultToJsonOptions.html">DefaultToJsonOptions</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Page.html">Page</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Page.html#assign">assign</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Page.html#.getFrom">getFrom</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Page.html#.newEmpty">newEmpty</a></span></li><li class="nav-heading">Namespaces</li><li class="nav-heading"><span class="nav-item-type type-namespace">N</span><span class="nav-item-name"><a href="Enum.html">Enum</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.has">Class.has</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.hasCode">Class.hasCode</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.hasName">Class.hasName</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.hasValue">Class.hasValue</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.of">Class.of</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.ofCode">Class.ofCode</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.ofName">Class.ofName</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.ofValue">Class.ofValue</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Enum.html#.Class.values">Class.values</a></span></li><li class="nav-heading"><span class="nav-item-type type-namespace">N</span><span class="nav-item-name"><a href="Model.html">Model</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#assign">assign</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#clear">clear</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#equals">equals</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#generateId">generateId</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#isEmpty">isEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#normalize">normalize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#normalizeField">normalizeField</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#toJsonString">toJsonString</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#validate">validate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#validateField">validateField</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.create">Class.create</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.createArray">Class.createArray</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.createPage">Class.createPage</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.isNullishOrEmpty">Class.isNullishOrEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Model.html#.Class.parseJsonString">Class.parseJsonString</a></span></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#ElementType">ElementType</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Label">Label</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#NameField">NameField</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#NonEmpty">NonEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Normalizable">Normalizable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Nullable">Nullable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Readonly">Readonly</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Timeout">Timeout</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Type">Type</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#Validatable">Validatable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#assign">assign</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#create">create</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createArray">createArray</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createDeferredReadonlyInitializer">createDeferredReadonlyInitializer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createImmediateReadonlyInitializer">createImmediateReadonlyInitializer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createPage">createPage</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#defaultNormalizer">defaultNormalizer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#defaultValidator">defaultValidator</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#enumNormalizer">enumNormalizer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isEnumClass">isEnumClass</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isEnumerator">isEnumerator</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isValidPageSource">isValidPageSource</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#normalize">normalize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#stringifyId">stringifyId</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#toJsonString">toJsonString</a></span></li>
28
28
  </nav>
29
29
 
30
30
  <div id="main">
@@ -56,8 +56,25 @@
56
56
  <a href="https://coveralls.io/github/Haixing-Hu/js-common-decorator?branch=master"><img src="https://coveralls.io/repos/github/Haixing-Hu/js-common-decorator/badge.svg?branch=master" alt="Coverage Status"></a></p>
57
57
  <p><a href="https://npmjs.com/package/@qubit-ltd/common-decorator">@qubit-ltd/common-decorator</a> is a JavaScript library of common decorators,
58
58
  provides decorators to add common methods to domain classes. The library
59
- supports the most recent (currently May 2023)
59
+ supports the most recent (currently November 2023)
60
60
  <a href="https://github.com/tc39/proposal-decorators">stage 3 proposal of JavaScript decorators</a>.</p>
61
+ <h2>Features</h2>
62
+ <ul>
63
+ <li><strong>Modern Decorator Support</strong>: Compatible with the latest Stage 3 proposal for JavaScript decorators</li>
64
+ <li><strong>Model Enhancement</strong>: <code>@Model</code> decorator adds common methods to domain model classes</li>
65
+ <li><strong>Enum Implementation</strong>: <code>@Enum</code> decorator provides Java-like enumeration capabilities</li>
66
+ <li><strong>Validation Support</strong>: <code>@Validatable</code> decorator enables field validation</li>
67
+ <li><strong>Normalization Support</strong>: <code>@Normalizable</code> decorator enables field normalization</li>
68
+ <li><strong>Type Safety</strong>: <code>@Type</code> and <code>@ElementType</code> decorators for type checking</li>
69
+ <li><strong>Serialization Utilities</strong>: Built-in JSON serialization/deserialization support</li>
70
+ </ul>
71
+ <h2>Installation</h2>
72
+ <pre class="prettyprint source lang-bash"><code># Using npm
73
+ npm install @qubit-ltd/common-decorator
74
+
75
+ # Using yarn
76
+ yarn add @qubit-ltd/common-decorator
77
+ </code></pre>
61
78
  <h2><span id="content">Table of Contents</span></h2>
62
79
  <ul>
63
80
  <li><a href="#usage">Usage</a>
@@ -1178,13 +1195,13 @@ const opt3 = DefaultOptions.merge('assign', null);
1178
1195
  expect(opt3.convertNaming).toBe(false);
1179
1196
  </code></pre>
1180
1197
  <h2><span id="configuration">Configuration</span></h2>
1181
- <p>This library uses the most recent (currently May 2023)
1198
+ <p>This library uses the most recent (currently November 2023)
1182
1199
  <a href="https://github.com/tc39/proposal-decorators">stage 3 proposal of JavaScript decorators</a>. Therefore, you must configure
1183
1200
  <a href="https://babeljs.io/">Babel</a> with <a href="https://babeljs.io/docs/babel-plugin-transform-class-properties">@babel/plugin-transform-class-properties</a> and the
1184
1201
  <a href="https://babeljs.io/docs/babel-plugin-proposal-decorators">@babel/plugin-proposal-decorators</a> plugins.</p>
1185
- <p><strong>NOTE:</strong> To support the <a href="https://github.com/tc39/proposal-decorator-metadata">stage 3 proposal of JavaScript decorator metadata</a>,
1186
- the version of the <a href="https://babeljs.io/">Babel</a> plugin <a href="https://babeljs.io/docs/babel-plugin-proposal-decorators">@babel/plugin-proposal-decorators</a> must be
1187
- at least <code>7.23.0</code>.</p>
1202
+ <p><strong>NOTE:</strong> To support the <a href="https://github.com/tc39/proposal-decorator-metadata">stage 3 proposal of JavaScript decorator metadata</a>
1203
+ at November 2023, the version of the <a href="https://babeljs.io/">Babel</a> plugin <a href="https://babeljs.io/docs/babel-plugin-proposal-decorators">@babel/plugin-proposal-decorators</a>
1204
+ must be at least <code>7.24.0</code>.</p>
1188
1205
  <h3><span id="webpack">Bundling with <a href="https://webpack.js.org/">webpack</a></span></h3>
1189
1206
  <ol>
1190
1207
  <li>Install the required dependencies:<pre class="prettyprint source lang-shell"><code>yarn add @qubit-ltd/common-decorator
@@ -1200,7 +1217,7 @@ configuration file <code>babelrc.json</code> is as follows:<pre class="prettypri
1200
1217
  ],
1201
1218
  &quot;plugins&quot;: [
1202
1219
  &quot;@babel/plugin-transform-runtime&quot;,
1203
- [&quot;@babel/plugin-proposal-decorators&quot;, { &quot;version&quot;: &quot;2023-05&quot; }],
1220
+ [&quot;@babel/plugin-proposal-decorators&quot;, { &quot;version&quot;: &quot;2023-11&quot; }],
1204
1221
  &quot;@babel/plugin-transform-class-properties&quot;
1205
1222
  ]
1206
1223
  }
@@ -1222,7 +1239,7 @@ file <code>babelrc.json</code> is as follows:<pre class="prettyprint source lang
1222
1239
  ],
1223
1240
  &quot;plugins&quot;: [
1224
1241
  &quot;@babel/plugin-transform-runtime&quot;,
1225
- [&quot;@babel/plugin-proposal-decorators&quot;, { &quot;version&quot;: &quot;2023-05&quot; }],
1242
+ [&quot;@babel/plugin-proposal-decorators&quot;, { &quot;version&quot;: &quot;2023-11&quot; }],
1226
1243
  &quot;@babel/plugin-transform-class-properties&quot;
1227
1244
  ]
1228
1245
  }
@@ -1301,7 +1318,590 @@ export default defineConfig({
1301
1318
  to open an issue or submit a pull request to the <a href="https://github.com/Haixing-Hu/js-common-decorator">GitHub repository</a>.</p>
1302
1319
  <h2><span id="license">License</span></h2>
1303
1320
  <p><a href="https://npmjs.com/package/@qubit-ltd/common-decorator">@qubit-ltd/common-decorator</a> is distributed under the Apache 2.0 license.
1304
- See the <a href="LICENSE">LICENSE</a> file for more details.</p></article>
1321
+ See the <a href="LICENSE">LICENSE</a> file for more details.</p>
1322
+ <h2>Front-end and Back-end Data Exchange Example</h2>
1323
+ <p>In real-world applications, data exchange between front-end and back-end is a common scenario. The following example demonstrates how to use this library to process data from RESTful APIs and send it back to the server.</p>
1324
+ <h3>Complete Example</h3>
1325
+ <p>Suppose we have an e-commerce application that needs to handle order data. The back-end API returns data in snake_case naming convention (e.g., <code>order_id</code>), while the front-end code uses camelCase (e.g., <code>orderId</code>). Additionally, order IDs use Java's Long type (which may exceed JavaScript's safe integer range).</p>
1326
+ <p>First, let's define our domain models:</p>
1327
+ <pre class="prettyprint source lang-javascript"><code>import { Model, Type, ElementType, Normalizable, Validatable, NonEmpty } from '@qubit-ltd/common-decorator';
1328
+
1329
+ // Configure default options for naming style conversion
1330
+ DefaultOptions.set('assign', {
1331
+ normalize: true,
1332
+ convertNaming: true,
1333
+ sourceNamingStyle: 'LOWER_UNDERSCORE', // JSON data format from back-end
1334
+ targetNamingStyle: 'LOWER_CAMEL' // Format used in front-end
1335
+ });
1336
+
1337
+ DefaultOptions.set('toJSON', {
1338
+ normalize: true,
1339
+ removeEmptyFields: true, // Automatically remove empty fields
1340
+ convertNaming: true,
1341
+ sourceNamingStyle: 'LOWER_CAMEL', // Format used in front-end
1342
+ targetNamingStyle: 'LOWER_UNDERSCORE' // Format to send to back-end
1343
+ });
1344
+
1345
+ // Define the OrderItem model
1346
+ @Model
1347
+ class OrderItem {
1348
+ constructor() {
1349
+ this.id = null; // Java Long type, automatically converted to BigInt
1350
+ this.productId = null; // Front-end uses camelCase, corresponding to product_id in back-end
1351
+ this.productName = '';
1352
+ this.quantity = 0;
1353
+ this.unitPrice = 0;
1354
+ }
1355
+
1356
+ @Normalizable
1357
+ @Validatable
1358
+ @Type(String)
1359
+ get productName() {
1360
+ return this._productName;
1361
+ }
1362
+
1363
+ set productName(value) {
1364
+ this._productName = value;
1365
+ }
1366
+
1367
+ @Normalizable
1368
+ @Validatable
1369
+ @Type(Number)
1370
+ get quantity() {
1371
+ return this._quantity;
1372
+ }
1373
+
1374
+ set quantity(value) {
1375
+ this._quantity = value;
1376
+ }
1377
+
1378
+ @Normalizable
1379
+ @Validatable
1380
+ @Type(Number)
1381
+ get unitPrice() {
1382
+ return this._unitPrice;
1383
+ }
1384
+
1385
+ set unitPrice(value) {
1386
+ this._unitPrice = value;
1387
+ }
1388
+
1389
+ // Calculate total price
1390
+ getTotalPrice() {
1391
+ return this.quantity * this.unitPrice;
1392
+ }
1393
+ }
1394
+
1395
+ // Define the Order model
1396
+ @Model
1397
+ class Order {
1398
+ constructor() {
1399
+ this.id = null; // Java Long type, automatically converted to BigInt
1400
+ this.orderNumber = ''; // Front-end uses camelCase, corresponding to order_number in back-end
1401
+ this.customerId = null;
1402
+ this.customerName = '';
1403
+ this.orderDate = null;
1404
+ this.orderItems = []; // Array of order items
1405
+ this.totalAmount = 0;
1406
+ this.status = '';
1407
+ this.note = ''; // Optional field, empty values will be removed when sent to back-end
1408
+ }
1409
+
1410
+ @Normalizable
1411
+ @Validatable
1412
+ @NonEmpty
1413
+ @Type(String)
1414
+ get orderNumber() {
1415
+ return this._orderNumber;
1416
+ }
1417
+
1418
+ set orderNumber(value) {
1419
+ this._orderNumber = value;
1420
+ }
1421
+
1422
+ @Normalizable
1423
+ @Validatable
1424
+ @Type(String)
1425
+ get customerName() {
1426
+ return this._customerName;
1427
+ }
1428
+
1429
+ set customerName(value) {
1430
+ this._customerName = value;
1431
+ }
1432
+
1433
+ @Normalizable
1434
+ @Validatable
1435
+ @Type(Date)
1436
+ get orderDate() {
1437
+ return this._orderDate;
1438
+ }
1439
+
1440
+ set orderDate(value) {
1441
+ this._orderDate = value;
1442
+ }
1443
+
1444
+ @Normalizable
1445
+ @Validatable
1446
+ @ElementType(OrderItem)
1447
+ get orderItems() {
1448
+ return this._orderItems;
1449
+ }
1450
+
1451
+ set orderItems(value) {
1452
+ this._orderItems = value;
1453
+ }
1454
+ }
1455
+
1456
+ // Example usage - Fetching data from back-end
1457
+ async function fetchOrder(orderId) {
1458
+ try {
1459
+ // Assume this is the response from a back-end API
1460
+ const response = await fetch(`/api/orders/${orderId}`);
1461
+ const data = await response.json();
1462
+
1463
+ // Sample data (in snake_case naming style)
1464
+ // {
1465
+ // &quot;id&quot;: &quot;9223372036854775807&quot;, // Note: Max value of Java Long, exceeds JS Number safe range
1466
+ // &quot;order_number&quot;: &quot;ORD-2023-001&quot;,
1467
+ // &quot;customer_id&quot;: &quot;5678&quot;,
1468
+ // &quot;customer_name&quot;: &quot;John Doe&quot;,
1469
+ // &quot;order_date&quot;: &quot;2023-08-15T14:30:00.000Z&quot;,
1470
+ // &quot;order_items&quot;: [
1471
+ // {
1472
+ // &quot;id&quot;: &quot;8345678912345678901&quot;, // Another large integer
1473
+ // &quot;product_id&quot;: &quot;101&quot;,
1474
+ // &quot;product_name&quot;: &quot;Laptop&quot;,
1475
+ // &quot;quantity&quot;: 1,
1476
+ // &quot;unit_price&quot;: 999.99
1477
+ // },
1478
+ // {
1479
+ // &quot;id&quot;: &quot;8345678912345678902&quot;,
1480
+ // &quot;product_id&quot;: &quot;202&quot;,
1481
+ // &quot;product_name&quot;: &quot;Wireless Mouse&quot;,
1482
+ // &quot;quantity&quot;: 2,
1483
+ // &quot;unit_price&quot;: 29.99
1484
+ // }
1485
+ // ],
1486
+ // &quot;total_amount&quot;: 1059.97,
1487
+ // &quot;status&quot;: &quot;PENDING&quot;,
1488
+ // &quot;note&quot;: null
1489
+ // }
1490
+
1491
+ // Create domain object using Order.create(), automatically handling naming style conversion and large integers
1492
+ const order = Order.create(data);
1493
+
1494
+ console.log(order.id); // Output: 9223372036854775807n (BigInt type)
1495
+ console.log(order.orderNumber); // Output: &quot;ORD-2023-001&quot; (converted to camelCase)
1496
+ console.log(order.orderItems[0].productName); // Output: &quot;Laptop&quot;
1497
+
1498
+ // Validation and normalization
1499
+ order.normalize();
1500
+ const validationResult = order.validate();
1501
+ if (!validationResult.valid) {
1502
+ console.error('Order data validation failed:', validationResult.message);
1503
+ }
1504
+
1505
+ return order;
1506
+ } catch (error) {
1507
+ console.error('Failed to fetch order:', error);
1508
+ throw error;
1509
+ }
1510
+ }
1511
+
1512
+ // Sending data back to the back-end
1513
+ async function updateOrder(order) {
1514
+ try {
1515
+ // Use toJSON to convert domain object to plain JavaScript object
1516
+ // Automatically handles: 1. Naming style conversion 2. Empty field removal 3. BigInt conversion
1517
+ const orderData = order.toJSON();
1518
+
1519
+ // Example of converted data format:
1520
+ // {
1521
+ // &quot;id&quot;: &quot;9223372036854775807&quot;, // BigInt converted to string, without 'n' suffix
1522
+ // &quot;order_number&quot;: &quot;ORD-2023-001&quot;,
1523
+ // &quot;customer_id&quot;: &quot;5678&quot;,
1524
+ // &quot;customer_name&quot;: &quot;John Doe&quot;,
1525
+ // &quot;order_date&quot;: &quot;2023-08-15T14:30:00.000Z&quot;,
1526
+ // &quot;order_items&quot;: [
1527
+ // {
1528
+ // &quot;id&quot;: &quot;8345678912345678901&quot;,
1529
+ // &quot;product_id&quot;: &quot;101&quot;,
1530
+ // &quot;product_name&quot;: &quot;Laptop&quot;,
1531
+ // &quot;quantity&quot;: 1,
1532
+ // &quot;unit_price&quot;: 999.99
1533
+ // },
1534
+ // // ...other order items
1535
+ // ],
1536
+ // &quot;total_amount&quot;: 1059.97,
1537
+ // &quot;status&quot;: &quot;PENDING&quot;
1538
+ // // Note: 'note' field was null and has been automatically removed
1539
+ // }
1540
+
1541
+ const response = await fetch(`/api/orders/${order.id}`, {
1542
+ method: 'PUT',
1543
+ headers: {
1544
+ 'Content-Type': 'application/json'
1545
+ },
1546
+ body: JSON.stringify(orderData) // No additional processing needed, already in the right format
1547
+ });
1548
+
1549
+ if (!response.ok) {
1550
+ throw new Error(`Failed to update order: ${response.status}`);
1551
+ }
1552
+
1553
+ return await response.json();
1554
+ } catch (error) {
1555
+ console.error('Failed to update order:', error);
1556
+ throw error;
1557
+ }
1558
+ }
1559
+
1560
+ // Example usage
1561
+ async function example() {
1562
+ // Fetch order data and modify it
1563
+ const order = await fetchOrder('123');
1564
+ order.status = 'COMPLETED';
1565
+ order.note = ''; // Empty string, will be removed when sent to back-end
1566
+
1567
+ // Add a new item to the order
1568
+ const newItem = new OrderItem();
1569
+ newItem.productId = '303';
1570
+ newItem.productName = 'Headphones';
1571
+ newItem.quantity = 1;
1572
+ newItem.unitPrice = 79.99;
1573
+ order.orderItems.push(newItem);
1574
+
1575
+ // Recalculate total amount
1576
+ order.totalAmount = order.orderItems.reduce(
1577
+ (sum, item) => sum + item.getTotalPrice(), 0
1578
+ );
1579
+
1580
+ // Send the updated order back to the server
1581
+ await updateOrder(order);
1582
+ }
1583
+
1584
+ </code></pre>
1585
+ <h3>Key Points</h3>
1586
+ <ol>
1587
+ <li>
1588
+ <p><strong>Automatic Naming Style Conversion</strong>:</p>
1589
+ <ul>
1590
+ <li>Data from the back-end uses snake_case format (e.g., <code>order_number</code>)</li>
1591
+ <li>Front-end domain objects use camelCase format (e.g., <code>orderNumber</code>)</li>
1592
+ <li>Through <code>DefaultOptions.set('assign', {...})</code> configuration, <code>Model.create()</code> and <code>model.assign()</code> automatically convert naming styles</li>
1593
+ <li>Through <code>DefaultOptions.set('toJSON', {...})</code> configuration, <code>model.toJSON()</code> automatically converts camelCase back to snake_case</li>
1594
+ </ul>
1595
+ </li>
1596
+ <li>
1597
+ <p><strong>Large Integer Handling</strong>:</p>
1598
+ <ul>
1599
+ <li>Back-end uses Java Long type IDs (e.g., <code>9223372036854775807</code>) that exceed JavaScript's safe integer range</li>
1600
+ <li><code>Model.create()</code> and <code>model.assign()</code> automatically convert these large integers to JavaScript's BigInt type</li>
1601
+ <li><code>model.toJSON()</code> automatically converts BigInt to the correct JSON format (without the 'n' suffix)</li>
1602
+ </ul>
1603
+ </li>
1604
+ <li>
1605
+ <p><strong>Empty Field Handling</strong>:</p>
1606
+ <ul>
1607
+ <li>With <code>removeEmptyFields: true</code> configuration, <code>model.toJSON()</code> automatically removes null, undefined, and empty string properties</li>
1608
+ <li>In the example, the 'note' field with null or empty string value won't be sent to the back-end</li>
1609
+ </ul>
1610
+ </li>
1611
+ <li>
1612
+ <p><strong>Type Conversion and Validation</strong>:</p>
1613
+ <ul>
1614
+ <li>Use <code>@Type</code> and <code>@ElementType</code> decorators to ensure type safety</li>
1615
+ <li>Use <code>model.normalize()</code> for data normalization</li>
1616
+ <li>Use <code>model.validate()</code> to validate data integrity</li>
1617
+ </ul>
1618
+ </li>
1619
+ </ol>
1620
+ <p>This complete example demonstrates how to use the features of this library to easily handle various challenges in front-end and back-end data exchange in real-world applications.</p>
1621
+ <h2>Advanced Usage</h2>
1622
+ <h3>Combining Multiple Decorators</h3>
1623
+ <p>You can combine multiple decorators to add rich functionality to your classes:</p>
1624
+ <pre class="prettyprint source lang-javascript"><code>import {
1625
+ Model,
1626
+ Type,
1627
+ ElementType,
1628
+ Normalizable,
1629
+ Validatable,
1630
+ NonEmpty
1631
+ } from '@qubit-ltd/common-decorator';
1632
+
1633
+ @Model
1634
+ class Product {
1635
+ constructor() {
1636
+ this.id = null;
1637
+ this.name = '';
1638
+ this.price = 0;
1639
+ this.tags = [];
1640
+ this.createdAt = null;
1641
+ }
1642
+
1643
+ @NonEmpty
1644
+ @Validatable
1645
+ @Normalizable
1646
+ @Type(String)
1647
+ get name() {
1648
+ return this._name;
1649
+ }
1650
+
1651
+ set name(value) {
1652
+ this._name = value;
1653
+ }
1654
+
1655
+ @Validatable
1656
+ @Normalizable
1657
+ @Type(Number)
1658
+ get price() {
1659
+ return this._price;
1660
+ }
1661
+
1662
+ set price(value) {
1663
+ this._price = value;
1664
+ }
1665
+
1666
+ @Normalizable
1667
+ @ElementType(String)
1668
+ get tags() {
1669
+ return this._tags;
1670
+ }
1671
+
1672
+ set tags(value) {
1673
+ this._tags = value;
1674
+ }
1675
+ }
1676
+
1677
+ // Usage
1678
+ const product = new Product();
1679
+ product.assign({
1680
+ name: ' Product Name ',
1681
+ price: '99.99',
1682
+ tags: ['tag1', 2, 'tag3']
1683
+ });
1684
+
1685
+ // After normalization, product.name will be trimmed,
1686
+ // product.price will be a Number,
1687
+ // and all elements in product.tags will be strings
1688
+ product.normalize();
1689
+
1690
+ console.log(product.validate()); // Checks if name is not empty and all types match
1691
+ </code></pre>
1692
+ <h3>Custom Validation and Normalization</h3>
1693
+ <p>You can implement custom validation and normalization logic:</p>
1694
+ <pre class="prettyprint source lang-javascript"><code>import { Model, Normalizable, Validatable } from '@qubit-ltd/common-decorator';
1695
+
1696
+ @Model
1697
+ class EmailSubscription {
1698
+ constructor() {
1699
+ this.email = '';
1700
+ this.subscribed = false;
1701
+ }
1702
+
1703
+ @Normalizable((value) => {
1704
+ // Custom normalizer that converts email to lowercase and trims whitespace
1705
+ return typeof value === 'string' ? value.toLowerCase().trim() : value;
1706
+ })
1707
+ @Validatable((value) => {
1708
+ // Custom validator that checks if email is valid
1709
+ if (typeof value !== 'string' || !value.includes('@')) {
1710
+ return {
1711
+ valid: false,
1712
+ message: 'Invalid email address',
1713
+ };
1714
+ }
1715
+ return { valid: true };
1716
+ })
1717
+ get email() {
1718
+ return this._email;
1719
+ }
1720
+
1721
+ set email(value) {
1722
+ this._email = value;
1723
+ }
1724
+ }
1725
+ </code></pre>
1726
+ <h3>Working with DefaultOptions</h3>
1727
+ <p>You can configure default options for various operations:</p>
1728
+ <pre class="prettyprint source lang-javascript"><code>import { DefaultOptions, Model } from '@qubit-ltd/common-decorator';
1729
+
1730
+ // Configure default options for JSON serialization
1731
+ DefaultOptions.set('toJSON', {
1732
+ normalize: true,
1733
+ removeEmptyFields: true,
1734
+ convertNaming: true,
1735
+ sourceNamingStyle: 'LOWER_CAMEL',
1736
+ targetNamingStyle: 'LOWER_UNDERSCORE'
1737
+ });
1738
+
1739
+ @Model
1740
+ class Order {
1741
+ constructor() {
1742
+ this.orderId = null;
1743
+ this.customerName = '';
1744
+ this.orderItems = [];
1745
+ }
1746
+ }
1747
+
1748
+ const order = new Order();
1749
+ order.assign({
1750
+ orderId: '12345',
1751
+ customerName: 'John Doe',
1752
+ orderItems: [
1753
+ { itemId: 1, name: 'Product 1', quantity: 2 }
1754
+ ]
1755
+ });
1756
+
1757
+ // Will use the configured default options for serialization
1758
+ const json = order.toJsonString();
1759
+ console.log(json);
1760
+ // Output will use lower_underscore naming:
1761
+ // {&quot;order_id&quot;:&quot;12345&quot;,&quot;customer_name&quot;:&quot;John Doe&quot;,&quot;order_items&quot;:[{&quot;item_id&quot;:1,&quot;name&quot;:&quot;Product 1&quot;,&quot;quantity&quot;:2}]}
1762
+ </code></pre>
1763
+ <h2>Integration Examples</h2>
1764
+ <h3>Using with Vue.js</h3>
1765
+ <pre class="prettyprint source lang-javascript"><code>import { Model, Normalizable, Validatable } from '@qubit-ltd/common-decorator';
1766
+ import { defineComponent, ref } from 'vue';
1767
+
1768
+ @Model
1769
+ class UserProfile {
1770
+ constructor() {
1771
+ this.username = '';
1772
+ this.email = '';
1773
+ this.bio = '';
1774
+ }
1775
+
1776
+ @Normalizable
1777
+ @Validatable
1778
+ get username() {
1779
+ return this._username;
1780
+ }
1781
+
1782
+ set username(value) {
1783
+ this._username = value;
1784
+ }
1785
+
1786
+ // Other getters and setters...
1787
+ }
1788
+
1789
+ export default defineComponent({
1790
+ setup() {
1791
+ const profile = ref(new UserProfile());
1792
+
1793
+ const updateProfile = (formData) => {
1794
+ profile.value.assign(formData);
1795
+ profile.value.normalize();
1796
+ const validation = profile.value.validate();
1797
+
1798
+ if (validation.valid) {
1799
+ // Save profile
1800
+ } else {
1801
+ // Handle validation errors
1802
+ console.error(validation.message);
1803
+ }
1804
+ };
1805
+
1806
+ return {
1807
+ profile,
1808
+ updateProfile
1809
+ };
1810
+ }
1811
+ });
1812
+ </code></pre>
1813
+ <h3>Using with Express.js</h3>
1814
+ <pre class="prettyprint source lang-javascript"><code>import express from 'express';
1815
+ import { Model, Normalizable, Validatable, NonEmpty } from '@qubit-ltd/common-decorator';
1816
+
1817
+ const app = express();
1818
+ app.use(express.json());
1819
+
1820
+ @Model
1821
+ class NewUserRequest {
1822
+ constructor() {
1823
+ this.username = '';
1824
+ this.email = '';
1825
+ this.password = '';
1826
+ }
1827
+
1828
+ @NonEmpty
1829
+ @Normalizable
1830
+ @Validatable
1831
+ get username() {
1832
+ return this._username;
1833
+ }
1834
+
1835
+ set username(value) {
1836
+ this._username = value;
1837
+ }
1838
+
1839
+ // Other getters and setters...
1840
+ }
1841
+
1842
+ app.post('/api/users', (req, res) => {
1843
+ try {
1844
+ const userRequest = NewUserRequest.create(req.body);
1845
+ userRequest.normalize();
1846
+ const validation = userRequest.validate();
1847
+
1848
+ if (!validation.valid) {
1849
+ return res.status(400).json({ error: validation.message });
1850
+ }
1851
+
1852
+ // Create user in database
1853
+ return res.status(201).json({ message: 'User created successfully' });
1854
+ } catch (error) {
1855
+ return res.status(500).json({ error: error.message });
1856
+ }
1857
+ });
1858
+
1859
+ app.listen(3000, () => {
1860
+ console.log('Server is running on port 3000');
1861
+ });
1862
+ </code></pre>
1863
+ <h2>Compatibility and Requirements</h2>
1864
+ <ul>
1865
+ <li><strong>Node.js</strong>: 14.x or higher</li>
1866
+ <li><strong>ECMAScript</strong>: ES2022 or higher</li>
1867
+ <li><strong>Decorator Support</strong>: Requires babel configuration for Stage 3 decorators</li>
1868
+ <li><strong>Browser Support</strong>: Modern browsers with ES6+ support</li>
1869
+ </ul>
1870
+ <h2>Best Practices</h2>
1871
+ <h3>Project Structure</h3>
1872
+ <p>When using this library, we recommend organizing your domain models in a structured way:</p>
1873
+ <pre class="prettyprint source"><code>src/
1874
+ ├── models/
1875
+ │ ├── base/
1876
+ │ │ └── BaseModel.js
1877
+ │ ├── User.js
1878
+ │ ├── Product.js
1879
+ │ └── Order.js
1880
+ ├── enums/
1881
+ │ ├── Status.js
1882
+ │ └── Role.js
1883
+ └── app.js
1884
+ </code></pre>
1885
+ <h3>Performance Considerations</h3>
1886
+ <ul>
1887
+ <li>Use <code>normalize()</code> only when necessary, not on every operation</li>
1888
+ <li>Consider caching validation results for frequently accessed objects</li>
1889
+ <li>For large collections, use <code>createArray()</code> method instead of mapping each item</li>
1890
+ </ul>
1891
+ <h3>Type Safety</h3>
1892
+ <p>While JavaScript is dynamically typed, this library provides several ways to ensure type safety:</p>
1893
+ <ol>
1894
+ <li>Use the <code>@Type</code> decorator to enforce type checking for properties</li>
1895
+ <li>Use the <code>@ElementType</code> decorator for arrays</li>
1896
+ <li>Enable normalization to automatically convert values to the correct type</li>
1897
+ </ol>
1898
+ <h3>Memory Management</h3>
1899
+ <p>When working with large object graphs:</p>
1900
+ <ol>
1901
+ <li>Avoid deep cloning unnecessarily</li>
1902
+ <li>Use the <code>removeEmptyFields</code> option in <code>toJSON</code> for large objects</li>
1903
+ <li>Be cautious with circular references when serializing objects</li>
1904
+ </ol></article>
1305
1905
  </section>
1306
1906
 
1307
1907
 
@@ -1315,7 +1915,7 @@ See the <a href="LICENSE">LICENSE</a> file for more details.</p></article>
1315
1915
 
1316
1916
  <footer>
1317
1917
  Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.4</a>
1318
- on Mon Jan 06 2025 12:29:37 GMT+0800 (China Standard Time)
1918
+ on Mon Apr 21 2025 02:07:33 GMT+0800 (China Standard Time)
1319
1919
  using the <a href="https://github.com/Haixing-Hu/jsdoc-minami">customized Minami theme</a>.
1320
1920
  </footer>
1321
1921