UNPKG

mosx

Version:

Multiview observable state management engine

89 lines (76 loc) 19.1 kB
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Serializer | Mosx Documentation</title> <meta name="generator" content="VuePress 1.5.2"> <meta name="description" content="State management framework"> <link rel="preload" href="/mosx/assets/css/0.styles.d0f6037d.css" as="style"><link rel="preload" href="/mosx/assets/js/app.e7b6d6a7.js" as="script"><link rel="preload" href="/mosx/assets/js/2.8b048e3e.js" as="script"><link rel="preload" href="/mosx/assets/js/14.50dee50d.js" as="script"><link rel="prefetch" href="/mosx/assets/js/10.30f5ca67.js"><link rel="prefetch" href="/mosx/assets/js/11.8bd80320.js"><link rel="prefetch" href="/mosx/assets/js/12.81130ef0.js"><link rel="prefetch" href="/mosx/assets/js/13.cad4915b.js"><link rel="prefetch" href="/mosx/assets/js/15.d234781f.js"><link rel="prefetch" href="/mosx/assets/js/3.a2975a35.js"><link rel="prefetch" href="/mosx/assets/js/4.f6e08b70.js"><link rel="prefetch" href="/mosx/assets/js/5.7b46edaa.js"><link rel="prefetch" href="/mosx/assets/js/6.689986cb.js"><link rel="prefetch" href="/mosx/assets/js/7.81819134.js"><link rel="prefetch" href="/mosx/assets/js/8.8ec53007.js"><link rel="prefetch" href="/mosx/assets/js/9.7ddab2d4.js"> <link rel="stylesheet" href="/mosx/assets/css/0.styles.d0f6037d.css"> </head> <body> <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/mosx/" class="home-link router-link-active"><!----> <span class="site-name">Mosx Documentation</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="http://github.com/udamir/mosx" target="_blank" rel="noopener noreferrer" class="nav-link external"> Github <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="http://github.com/udamir/mosx" target="_blank" rel="noopener noreferrer" class="nav-link external"> Github <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav> <ul class="sidebar-links"><li><a href="/mosx/" aria-current="page" class="sidebar-link">Introduction</a></li><li><a href="/mosx/overview.html" class="sidebar-link">Overview</a></li><li><a href="/mosx/mosx-api.html" class="sidebar-link">Mosx API</a></li><li><a href="/mosx/tracker-api.html" class="sidebar-link">Tracker API</a></li><li><a href="/mosx/serializer.html" aria-current="page" class="active sidebar-link">Serializer</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/mosx/serializer.html#concept" class="sidebar-link">Concept</a></li><li class="sidebar-sub-header"><a href="/mosx/serializer.html#mpackserializer" class="sidebar-link">MpackSerializer</a></li><li class="sidebar-sub-header"><a href="/mosx/serializer.html#lightserializer" class="sidebar-link">LightSerializer</a></li><li class="sidebar-sub-header"><a href="/mosx/serializer.html#schemaserializer" class="sidebar-link">SchemaSerializer</a></li><li class="sidebar-sub-header"><a href="/mosx/serializer.html#custom-serializer" class="sidebar-link">Custom Serializer</a></li></ul></li><li><a href="/mosx/examples.html" class="sidebar-link">Examples</a></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="serializer"><a href="#serializer" class="header-anchor">#</a> Serializer</h1> <h2 id="concept"><a href="#concept" class="header-anchor">#</a> Concept</h2> <p>By default all patches and snapshotes are not serialized</p> <p>The following serializers are currently avalible:</p> <ul><li>MpackSerializer</li> <li>LightSerializer</li> <li>SchemaSerializer</li></ul> <h2 id="mpackserializer"><a href="#mpackserializer" class="header-anchor">#</a> <strong>MpackSerializer</strong></h2> <p>Simple serializer based on <a href="https://msgpack.org/" target="_blank" rel="noopener noreferrer">messagePack<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>. Patch converted to array format and then encoded with <a href="https://github.com/darrachequesne/notepack" target="_blank" rel="noopener noreferrer">notepack.io<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> serialization. DecodeMap is not required for decoding:</p> <p>Zero array element is used for patch.op converted to number:</p> <table><thead><tr><th>patch.op</th> <th>op</th></tr></thead> <tbody><tr><td>&quot;add&quot;</td> <td>0</td></tr> <tr><td>&quot;replace&quot;</td> <td>1</td></tr> <tr><td>&quot;remove&quot;</td> <td>2</td></tr></tbody></table> <p>First array element for patch.path, others elements for patch.value and patch.oldValue.</p> <p>Example of Json patch:</p> <div class="language-json extra-class"><pre class="language-json"><code><span class="token punctuation">{</span> <span class="token property">&quot;op&quot;</span><span class="token operator">:</span> <span class="token string">&quot;add&quot;</span><span class="token punctuation">,</span> <span class="token property">&quot;path&quot;</span><span class="token operator">:</span> <span class="token string">&quot;/players/0&quot;</span><span class="token punctuation">,</span> <span class="token property">&quot;value&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;1&quot;</span><span class="token punctuation">,</span> <span class="token property">&quot;name&quot;</span><span class="token operator">:</span> <span class="token string">&quot;John&quot;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre></div><p>Patch converted to array:</p> <div class="language-ts extra-class"><pre class="language-ts"><code><span class="token punctuation">[</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">&quot;/players/0&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token string">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;1&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;name&quot;</span><span class="token operator">:</span> <span class="token string">&quot;John&quot;</span> <span class="token punctuation">}</span> <span class="token punctuation">]</span> </code></pre></div><h2 id="lightserializer"><a href="#lightserializer" class="header-anchor">#</a> <strong>LightSerializer</strong></h2> <p>Simple serializer based on messagePack and with static decodeMap. DecodeMap will added to encoded snapshot and required for decoding.</p> <p>Patch converted to tuple array format, <code>patch.path</code> converted from string to bytes with indexes in static decode Map. The algoritms is following - patch consists of 2 parts: header and body:</p> <ul><li>Header includes excoded patch.op and patch.path</li> <li>Body includes array of params and value/oldValue and encoded with notepack.io</li></ul> <p>When light serializer used patch endoded in following way:</p> <table><thead><tr><th></th> <th>0</th> <th>1</th> <th>2...n+2</th> <th>n+3...</th></tr></thead> <tbody><tr><td>byte</td> <td>op</td> <td>n</td> <td>path</td> <td>[...params, value, oldValue]*</td></tr></tbody></table> <p>&quot;*&quot; - encoded with notepack</p> <p>Zero byte is used for operation:</p> <table><thead><tr><th>patch.op</th> <th>op</th></tr></thead> <tbody><tr><td>&quot;add&quot;</td> <td>0</td></tr> <tr><td>&quot;replace&quot;</td> <td>1</td></tr> <tr><td>&quot;remove&quot;</td> <td>2</td></tr></tbody></table> <p>First byte is used for path size - number of nodes in <code>patch.path</code> (x2 byte for each)</p> <p>From second byte to n + 2 path encoded:</p> <table><thead><tr><th>byte</th> <th>option 1</th> <th>option 2</th></tr></thead> <tbody><tr><td>0</td> <td>typeIndex</td> <td>-1</td></tr> <tr><td>1</td> <td>propIndex</td> <td>paramIndex</td></tr></tbody></table> <p>All map keys are not included in static encode Map as they are dynamic, so all keys added to body array. patch.value and patch.oldValue also added to body array and encode with notepack.io</p> <h2 id="schemaserializer"><a href="#schemaserializer" class="header-anchor">#</a> <strong>SchemaSerializer</strong></h2> <p>This serializer based on <a href="https://github.com/udamir/patchpack" target="_blank" rel="noopener noreferrer">patchPack<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> library. The main difference from &quot;light&quot; version is that dynamic decode Map will be used (schema). Schema will be updated by decoding snapshot and patches. This serialize algorithm minimize size of encoded patch.</p> <div class="custom-block warning"><p class="custom-block-title">WARNING</p> <p>tracker parameter <code>privateMapValuePatch = true</code> will be applied.</p></div> <h3 id="schema-format"><a href="#schema-format" class="header-anchor">#</a> Schema format</h3> <p>As in LightSerializer decodeMap included in encoded snapshot.</p> <div class="language-ts extra-class"><pre class="language-ts"><code> <span class="token keyword">const</span> tracker <span class="token operator">=</span> Mosx<span class="token punctuation">.</span><span class="token function">createTracker</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> <span class="token punctuation">{</span> serializer<span class="token operator">:</span> SchemaSerializer <span class="token comment">// privateMapValuePatch: true</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">const</span> snapshot <span class="token operator">=</span> tracker<span class="token punctuation">.</span><span class="token function">snapshot</span><span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre></div><h2 id="custom-serializer"><a href="#custom-serializer" class="header-anchor">#</a> Custom Serializer</h2> <p>You can build your own serializer extending <code>Serializer</code> class:</p> <div class="language-ts extra-class"><pre class="language-ts"><code><span class="token keyword">class</span> <span class="token class-name">CustomSerializer</span> <span class="token keyword">extends</span> <span class="token class-name">Serializer</span><span class="token operator">&lt;</span><span class="token constant">T</span> <span class="token operator">=</span> <span class="token builtin">any</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span> <span class="token comment">// tree nodes</span> <span class="token keyword">public</span> nodes<span class="token operator">:</span> WeakMap<span class="token operator">&lt;</span><span class="token builtin">any</span><span class="token punctuation">,</span> ITreeNode<span class="token operator">&gt;</span> <span class="token comment">// tracker listeneres</span> <span class="token keyword">public</span> listeneres<span class="token operator">:</span> Set<span class="token operator">&lt;</span>IListener<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;&gt;</span> <span class="token comment">// state tree root</span> <span class="token keyword">public</span> root<span class="token operator">:</span> <span class="token constant">T</span> <span class="token keyword">public</span> <span class="token function">onCreate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// on serializer create</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">beforeChange</span><span class="token punctuation">(</span><span class="token parameter">change<span class="token operator">:</span> IChange<span class="token punctuation">,</span> parent<span class="token operator">:</span> ITreeNode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// before sending patches to listeners</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">afterChange</span><span class="token punctuation">(</span><span class="token parameter">change<span class="token operator">:</span> IChange<span class="token punctuation">,</span> parent<span class="token operator">:</span> ITreeNode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// after sending patches to listeners</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">onCreateNode</span><span class="token punctuation">(</span><span class="token parameter">entry<span class="token operator">:</span> ITreeNode<span class="token punctuation">,</span> target<span class="token operator">:</span> <span class="token builtin">any</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// on create new tree node</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">onDeleteNode</span><span class="token punctuation">(</span><span class="token parameter">entry<span class="token operator">:</span> ITreeNode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// on delete tree node</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">encodeSnapshot</span><span class="token punctuation">(</span>value<span class="token operator">:</span> <span class="token builtin">any</span><span class="token punctuation">)</span><span class="token operator">:</span> Buffer <span class="token punctuation">{</span> <span class="token comment">// add encode snapshot algorithms</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">decodeSnapshot</span><span class="token punctuation">(</span>value<span class="token operator">:</span> Buffer<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">any</span> <span class="token punctuation">{</span> <span class="token comment">// add decode snapshot algorithms</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">encodePatch</span><span class="token punctuation">(</span>patch<span class="token operator">:</span> IReversibleJsonPatch<span class="token punctuation">,</span> target<span class="token operator">:</span> <span class="token builtin">any</span><span class="token punctuation">)</span><span class="token operator">:</span> Buffer <span class="token punctuation">{</span> <span class="token comment">// add encode patch algorithms</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">decodePatch</span><span class="token punctuation">(</span>buffer<span class="token operator">:</span> Buffer<span class="token punctuation">)</span><span class="token operator">:</span> IReversibleJsonPatch <span class="token punctuation">{</span> <span class="token comment">// add decode patch algorithms</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre></div></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev"><a href="/mosx/tracker-api.html" class="prev"> Tracker API </a></span> <span class="next"><a href="/mosx/examples.html"> Examples </a></span></p></div> </main></div><div class="global-ui"></div></div> <script src="/mosx/assets/js/app.e7b6d6a7.js" defer></script><script src="/mosx/assets/js/2.8b048e3e.js" defer></script><script src="/mosx/assets/js/14.50dee50d.js" defer></script> </body> </html>