{"_id":"o-snapshot","_rev":"8-1d426fe604159f3229f5e2a93d593718","name":"o-snapshot","dist-tags":{"latest":"2.0.0"},"versions":{"1.0.0":{"name":"o-snapshot","version":"1.0.0","description":"Objects serializer for NodeJS","main":"index.js","scripts":{"test":"npx mocha --config ./utilities-config/.mocharc.json"},"keywords":["serialization"],"author":{"name":"Martin Rubi"},"license":"ISC","homepage":"https://bitbucket.org/haijin-development/snapshot","devDependencies":{"o-testing-toolbox":"^1.0.1","chai":"^4.2.0","eslint":"^7.10.0","eslint-config-standard":"^14.1.1","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.2.1","eslint-plugin-standard":"^4.0.1","mocha":"^7","nyc":"^15.0.0"},"dependencies":{"o-toolbox":"1.2.0"},"gitHead":"f15587696bc139e9a38ae00a6098846514246aea","_id":"o-snapshot@1.0.0","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-tFFFFjHij6gYl5WyzY6bRT86b6s1Ql+kn2ClwyjOAat2eJjGJW0ssHvAQN2Y5O3Hky3/93ZYsmb2cZiIJl+3JA==","shasum":"0e239531c6114c62e5fe6b51e9b4e915600523be","tarball":"https://registry.npmjs.org/o-snapshot/-/o-snapshot-1.0.0.tgz","fileCount":23,"unpackedSize":55366,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfdGRICRA9TVsSAnZWagAA4lgP/RCWsijYQwDOiqKkNZ3Y\n1ujPAPAtXqoVJImZzyHBMt3JlHPxGvX9HmVET6TCn9urSCd6Ye/QpxVm/t8J\nYYYR+IoBK9UfuQQoLdsVCrjvKxHplge1AKpRzPOYIYwT2vEO51Ger1Mv9PBg\nIqOvEprAQ+UHxxqeF6NyKCAL4fA3XyGJzMWMzGLkNNfdhmkHttE7oxYzRhzQ\nOg22C+E9nuO3k7jZin6ZqAgOP6FH+JufyyRSoQFF/xJKQyVHUoGdmm4A2KzH\nZLd6Oqt2o6t87nD2nzXcqnAdAuxDgcZK5csQV028r/V+Kn2ndUW7yRPrhveG\nndnn3nJn/e9vyjCbE976Tf8LGtnmlKOvoUaalAWqUYiCzE6nikKv7v3M3tFO\nQWFyepFR9ei5JQP/pMlN19Ud40ThgxFV8D6bpqU3hHPedC1H4G7TCTdZX2qk\nue+Z+fYzhJrceLfV/BfZvKvKDZ/71jcw4jOHntsX5c8z79+bBkDdb6KSWB/Q\nsLnXSaaKfyzBg+dbTwP816m9Dq5uq/4HUxi1LhpruXzcveXAVnY89gfXHhhD\nje6gi02ZWZfvCr55wmAROGK/3vtLITKAhIWkn9CY9DlK9qp2H5NFoS5UIk6B\nZpeMvO1fe+pAW1dchtTQ+eaD0+x/7269NQhRu6Cp6vXBDzAj7dlywtJV8M0R\njFNV\r\n=WG2V\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDV3LuqWFU8vG7FkuZzuHZ6ZCLaWpP0D4B6j39OJuqoVAiEAsMeEGmxy0ZCTFOqDZHdGwO/OdCKec12PK8RFAdj3gps="}]},"maintainers":[{"name":"haijindev","email":"haijin.development@gmail.com"}],"_npmUser":{"name":"haijindev","email":"haijin.development@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-snapshot_1.0.0_1601463367602_0.5968578908712545"},"_hasShrinkwrap":false},"1.0.1":{"name":"o-snapshot","version":"1.0.1","description":"Objects serializer for NodeJS","main":"index.js","scripts":{"test":"npx mocha --config ./utilities-config/.mocharc.json"},"keywords":["serialization"],"author":{"name":"Martin Rubi"},"license":"ISC","homepage":"https://bitbucket.org/haijin-development/snapshot","devDependencies":{"o-testing-toolbox":"^2.0.0","chai":"^4.2.0","eslint":"^7.11.0","eslint-config-standard":"^14.1.1","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.2.1","eslint-plugin-standard":"^4.0.1","mocha":"^7","nyc":"^15.0.0"},"dependencies":{"o-toolbox":"2.0.0"},"gitHead":"4b41d4421d8c125f6a74fda164396c922f806dce","_id":"o-snapshot@1.0.1","_nodeVersion":"14.12.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-s+kXEqinQLPibo1GH5Og+tsU8QAQcOusiAYiwiEpUqV86IxitUOtA7dpgJLGnJJkQUVTrZrTiFbqqdg8/TSW4g==","shasum":"fe322742d602d72bca6a60b97ad8825198e348b5","tarball":"https://registry.npmjs.org/o-snapshot/-/o-snapshot-1.0.1.tgz","fileCount":23,"unpackedSize":55415,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiyqBCRA9TVsSAnZWagAAaMcP/2s+hwavwBxwopTY9p4Z\nadq+LXJwqDuwnMA/hY3H5vEohjUc0fVqdpaRI58pXJ9GpJ9g6cEZL/5kAqxX\nGiWki85Zq+6cdLF5htdoZ+029VjryGrWlJIYG9Im3NgGGedAqin/ca0JcVrk\n1kruE8IudU+aTEEOUPPMdfamxz/ZOSGqx+tFmwY1t5R0fjYtpaYwYEB01Ags\nCWxdb3HPAUoZ5ILpjzpd3RUNwZn21oFpgCEeHJr5X0abi32paci4eC6ZVZVz\nQVCZwSiTJu3PJyDSXx812VrOZ3u1HGgn9814qB+8tY+yOdk1m9fWyfP55DAt\nexTzZk9Gv17PoXdKFy/91j4LBJxP9/xyZVu8YRZUCIOYl92FcGOuR2HZ4FmK\nrzl2OgGB7WxEE7GMolwWJts940dYuaJXS63r36C7VSLYKk0QGsMr3PKophCd\nQ2ymZ0OHKxda4lHBcGwuOHQTTWHWFwrBpkKTJXVwUi5ueNmyvrke+h5ACriS\nLnkn4io8IdtJyGLNaw7uYzVq2oH2yMVWy4iBN0CMItbm+ndn14VWxu0+x8Bl\nGT6nrTc1LVmUfyMGfHX5wKNujH3OWPoledpcJTIhCzTq423fqNIiU3I2vV7d\n3X4ofT627YrRWSTbYWbSIf2/Leywp5nCBntOFLV8BjWRzGGnFAvBc6ue1/vN\n82YS\r\n=IM7/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA6dLbcoAIsoYWfPz1w0TvupFmOcAH/3I7ajoGRqwqlHAiA6tiy3yFKuMSYUzgXhYNp1dQTyoF81pDLz7sopgfERhA=="}]},"maintainers":[{"name":"haijindev","email":"haijin.development@gmail.com"}],"_npmUser":{"name":"haijindev","email":"haijin.development@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-snapshot_1.0.1_1602955904957_0.2669772834643458"},"_hasShrinkwrap":false},"1.0.3":{"name":"o-snapshot","version":"1.0.3","description":"Objects serializer for NodeJS","main":"index.js","scripts":{"test":"npx mocha --config ./utilities-config/.mocharc.json"},"keywords":["serialization"],"author":{"name":"Martin Rubi"},"license":"ISC","homepage":"https://bitbucket.org/haijin-development/snapshot","devDependencies":{"o-testing-toolbox":"^2.0.0","chai":"^4.2.0","eslint":"^7.13.0","eslint-config-standard":"^16.0.1","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.2.1","eslint-plugin-standard":"^4.0.2","mocha":"^7","nyc":"^15.1.0"},"dependencies":{"o-toolbox":"^2.1.0"},"gitHead":"f2ebf02e3635868711d8597a89cae9f5dfbc1914","_id":"o-snapshot@1.0.3","_nodeVersion":"12.16.2","_npmVersion":"6.14.4","dist":{"integrity":"sha512-+j6dud+yNvhPFsiAzTG7fSKqkgxUVzzAHUzONhLwjNt7IsxhhjhsZGBzliIFhOVGcDHN42BfOReUkKKvpW9iVg==","shasum":"d049fbaa46a4902f933da3e8bc41b8c16152b384","tarball":"https://registry.npmjs.org/o-snapshot/-/o-snapshot-1.0.3.tgz","fileCount":23,"unpackedSize":55424,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfqEK3CRA9TVsSAnZWagAAtsQQAIsk4FgieUrzBDUblaqQ\nNU/v9/htk3T4GUSZcM0qPiEdMYgmWWTZKQPhnDLLk2rEabPxHFt4pJC7Agin\nq6zm+CyhUZQeDx+9w3AV+aX/8noDR82QReG54p0nxpfWn7zC1CJ6/Rw8woYH\ntdyNgjAT+52r//cVUWHeH9iuaGqqXljD0aPjaWqqKsknUEiFIPvAz47NH9rO\nAEZa0EU4Q9OWXHHGuM/hJveANYhjNqY+MMuTI+oHi2Q+IBVg24XSTKx/jTdw\nFWgyg56HrxkWp7ouRxl9GgtF0MycTxQZP7hXneV8X2gIRCZYEUAn/jkF3DWz\ncEaxXkrFK8skwOwX+TNYSQIP32jsNIIlYcyA+efvBZZUYRkJhAVu3tIzy4Y+\nlt5Qxd9+jZPZRfxQmOxsHbz9Gk6e0kJYWjM+2uNqVQAMhnpjmz80RiBIA27T\n739gdNaTyPxCOXuhVKrdiU5GPkIliNmwGknofFSZ1Y3vT/ZxydxtgqjRwnOo\nEkP172zrsjTXY0cf+6t8JvSceFBEXNIAs+UGy3fzICLWQmdQUX8+IFfiiVf1\nm0i7L6ta0n77FXtL/Qom12VFTUspwtM7mJ4bLcV3hdglZtDUNG5azRxkR4Qu\nZYPlcTWzdvl+g+vepqlHIPI3gFfrFtCwOtbDplcntjqpFONwRAUL+3v5X2z9\n2Rnt\r\n=nXZb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDO/0vi3D+gTD1VqSqePDKe44OJ+dR5yKBtRZ/wOoatiAIgAYQrNxrjjZ3ninpoLxX9gf+R4U8ahOlGzqsqRekHL4A="}]},"_npmUser":{"name":"haijindev","email":"haijin.development@gmail.com"},"directories":{},"maintainers":[{"name":"haijindev","email":"haijin.development@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-snapshot_1.0.3_1604862647023_0.423504632535022"},"_hasShrinkwrap":false},"1.0.4":{"name":"o-snapshot","version":"1.0.4","description":"Objects serializer for NodeJS","main":"index.js","scripts":{"test":"npx mocha --config ./utilities-config/.mocharc.json"},"keywords":["serialization"],"author":{"name":"Martin Rubi"},"license":"ISC","homepage":"https://bitbucket.org/haijin-development/snapshot","devDependencies":{"o-testing-toolbox":"^2.0.1","chai":"^4.2.0","eslint":"^7.13.0","eslint-config-standard":"^16.0.1","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.2.1","eslint-plugin-standard":"^4.1.0","mocha":"^7","nyc":"^15.1.0"},"dependencies":{"o-toolbox":"^3.0.0"},"gitHead":"9e1b2e75dd223aefdc729549f4d74e271e186933","_id":"o-snapshot@1.0.4","_nodeVersion":"14.12.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-+Ww51jrWN9oiDDD0LZ1JulShBBvo4/oquaFQP9l0Ai3ycT1VzSMI04CCGIaYhkUpMep/cKcWuOCT7AnfRTsIfQ==","shasum":"7922e609e73d271f984d774fb4b9c864317f4d13","tarball":"https://registry.npmjs.org/o-snapshot/-/o-snapshot-1.0.4.tgz","fileCount":23,"unpackedSize":55424,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfsBqdCRA9TVsSAnZWagAAULEP/j2apw0vwrA5ik5gsGBh\nDH3vBHoUZJg81CD6uobeDk1YPN+egmC5xnDC7TgNRGogfrJV/n0j9ZZRD8NV\nsDyVl4G38/Hgu5HJXBVYRQnGXljKdemddH5rk5Hzyllt6pG9jaToGP/mVrdl\nJJicRb7rhaOeAxsMUKPEBOWbTmoFYUap/j7a99glN5S4SE8VMAXav5NSZELb\n8K7bIoG8H5y6LPA1/JtKNuI+yB3u51SNBKbWfAhK8odi1KLekztHv8usQnT3\nQr4ckj0gaWpAy89bL3PGsTEqWU4cNyMlAjYqB8WEFHMiJPa0FOV/hzeUGQUo\nIdHhXkgT5ex0qAopzU35G7VXAfFW7T6ndz6obHU1iyp2NLdi4WutFqEgA8DX\ngQoT2wur/Zuv45yQw+z80GAC6nHz5ACsFgr4DbMVXVs5bFZKPr2kzdT9rCrv\nw7t4DJDbI8Ukj0P29c9J4hLPXk4HhMDySpAkgrkqVWU8gMrufAr4q0+iwXj3\nBJVYLru6VeFYgKK06PPjK2CI1HmFidxB36TEwh/sbA06Wn2vb8W1IU0S1neM\n3csHtavVkBUyJpTBP+C3bxeJU0FSkcynru4wNPAFx6uuKpd0hnZ8k/HkIvke\n5NjIr3/hxlOeve3GdfrXEktqaAkCUPOSwuS5gccb0AQUlLEjdw0yA3ZS+0Ir\nM7RY\r\n=P3sn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEJC5SU9VNlO9lCtQUEeW1SkW98Y/ZexeQQb43JMkt1FAiAJG2nlAtluT+PPdQsYB7bJ6nAfzQEbybFDwaQbmUcyjQ=="}]},"_npmUser":{"name":"haijindev","email":"haijin.development@gmail.com"},"directories":{},"maintainers":[{"name":"haijindev","email":"haijin.development@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-snapshot_1.0.4_1605376669446_0.5554261423575944"},"_hasShrinkwrap":false},"1.0.5":{"name":"o-snapshot","version":"1.0.5","description":"Objects serializer for NodeJS","main":"index.js","scripts":{"clean":"rm -rf node_modules && rm -f package-lock.json","test":"npx mocha --config ./utilities-config/.mocharc.json"},"keywords":["serialization"],"author":{"name":"Martin Rubi"},"license":"ISC","homepage":"https://bitbucket.org/haijin-development/snapshot","devDependencies":{"o-testing-toolbox":"^2.0.1","chai":"^4.2.0","eslint":"^7.16.0","eslint-config-standard":"^16.0.1","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.2.1","eslint-plugin-standard":"^5.0.0","mocha":"^7","nyc":"^15.1.0"},"dependencies":{"o-toolbox":"^4.0.0"},"gitHead":"b231cea37d66b80e886777edba1c8024e2851ede","_id":"o-snapshot@1.0.5","_nodeVersion":"14.15.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-JyrypzO2Zz1PN4ZT2LKcIp6+D1nmh52ygR1226qToTlgM9av0hYrhVqLqpjO+D3rh4U73dwWajnQfRIxKwEGrQ==","shasum":"2af4db0e3b021e60d433f8848c4c4688b85ffe21","tarball":"https://registry.npmjs.org/o-snapshot/-/o-snapshot-1.0.5.tgz","fileCount":24,"unpackedSize":55097,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf525qCRA9TVsSAnZWagAApvQP/0VlGSNiI0nVGK6qR59M\nmdKWs5ua+PkgL3+sjVSwB9O9Llf4HAQbHL0IQ8b35vitVqIux3R5ZEEttlcF\npTeJFcY6QHQPYT2JfIWmW4wmPRHtceBfNGojafF8Tp0dtpqSK4uD5nCHX5sb\n4WVfT206xCLe/AonI6Ky6sEqICN7W4NHXZFLyuxA4etgmyepRKULX2RPRuy5\nEbs4kBR6ndpRhuuNCDTpGtUbzGzCVVEE3yD7sAXLawwD0FRtSK/9F4xVGGxZ\nPFsCY1vgLKoJkPW4zI0n+aDpxOzp3hq/46f01eVdW62so0S0Hm0EdmL1n6z5\nBu7x1yfZ2AwgCcvkrAYchvPJzGgE/x+1Kvrr7MlJczwSTDEjqkuqkMt8uaz4\nHYtClB/VFkgbxllBBFdbD/OtMsNjPoT1HLDxNPRiRla7gSySiAvk8x9GG3yb\nF3pPuEKtdoinqxt93GpRmstfRxFZ49qCMME4bYMfI+IhxpJ2MVGErIUX/XJn\nSOVPypHtDLtBym4byzl7UUe4+lgkjHHnXFFwyoOe22J0mss0l3RcRnZGWM1B\ntd4ExR1S3X70U3kGB2ljib2SNUqQQecPSVn4yTMPJ85P2X1/wXyPJyjG+rDK\nq6yjuCb12DcCQrmiTCh2vnIBWFylIwX2dGSURI5soRv6uLa1uM4S5G/Ty5q/\nz2Fz\r\n=sf8Y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID+ZgxmaqzDk+/yg3tZziFDGDm2JafK0+LBWtKaDn2PnAiEA1upS98wci4DZdfklCjPGS4Y7qogfu9+FyDCtT+lsoCE="}]},"_npmUser":{"name":"haijindev","email":"haijin.development@gmail.com"},"directories":{},"maintainers":[{"name":"haijindev","email":"haijin.development@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-snapshot_1.0.5_1609002602246_0.3408688882235775"},"_hasShrinkwrap":false},"1.0.6":{"name":"o-snapshot","version":"1.0.6","description":"Objects serializer for NodeJS","main":"index.js","scripts":{"clean":"rm -rf node_modules && rm -f package-lock.json","test":"npx mocha --config ./utilities-config/.mocharc.json"},"keywords":["serialization"],"author":{"name":"Martin Rubi"},"license":"ISC","homepage":"https://bitbucket.org/haijin-development/snapshot","devDependencies":{"o-testing-toolbox":"^2.0.1","chai":"^4.2.0","eslint":"^7.16.0","eslint-config-standard":"^16.0.1","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.2.1","eslint-plugin-standard":"^5.0.0","mocha":"^7","nyc":"^15.1.0"},"dependencies":{"o-toolbox":"^4.0.0"},"gitHead":"daf458cb93ceb82beb58e81a0bbfe4f3c3e4ea65","_id":"o-snapshot@1.0.6","_nodeVersion":"14.15.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-tYU9pZfUrGZH0AFe56PZoJ0MA3W4MuJmpmGHRmTTpfbpKRpAI+01E/fFaD8BqMaiRodWcaY+MJ+o7DH3gOieSg==","shasum":"b218c5bd0ff7a862b7325a6e9815ebf087ed0a18","tarball":"https://registry.npmjs.org/o-snapshot/-/o-snapshot-1.0.6.tgz","fileCount":26,"unpackedSize":76149,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf737yCRA9TVsSAnZWagAAWHcQAIudalDffonE6oHFPy7R\npJtiwWmcaFpXruMoKTgzCFgOrkuimI/Z14Es8ywJ628bvQ6yee4K5O0Beu0/\nOMpX39bV343sCRQeANk6Ts8oTeMnJVJKUY34e9lmr0S2vpTZggpHWHVs96Um\nT1qt6EdtnXNqf3PMgSt0hoXTZBqHLWGNQ0mAITHLlEN7tUDHW8tQ17gRPriH\nVKcMKPwGzFT+gwVpwn70wk/6c7l4w2xkfJTr5q/Nk8N/MMeyWrrdTufwnnPk\nFn6Qyb7eBjOzrXaWeYMMEdenwf7ml2nlLrhEWltrPwH4cpiqVbuVOR9iHAs/\nFWfqCu5QIb+fzyPC3Ko6fXa0Cq6acaIPfzt2rUaVxtTttzjNBBMJ/VDTN8bV\nwrcjtSjb8MP5+AzHP0Cl0mraIkVJ8z1IWoWiwpXMaR6EaxyB+UHNFbjTNTkI\nQklpFCXcA5i9XKXzvMkCwSw8p3SyGIE3PXlqk7/mSUwoSpQXsnar3FE2V4BY\nPoF0jxq5aeXijY4TXRLxaLH1BZ9UQWHvdeJQrlav31nTlwFOw3ib9WKAbCL2\nGaU1DGybx5nb08aO2vvlkNqIgx+9fO0tDJ7MLg9JzD21htAnAH/rQF3dNRG+\n6owZde4Fory4EedqcJEq5fQsnn14tz+dLuJslLybVR1KsE0X5J5LK2mUZaIs\nN+3q\r\n=iKKx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCgJ/InA3Ux2HSe0VRKhQXVQ585XtFtU8gZog1uy05J7gIhAPUkqzrF8Z2+YQpkpDnyoNNurGYwf0SfXty6JHCMa7oY"}]},"_npmUser":{"name":"haijindev","email":"haijin.development@gmail.com"},"directories":{},"maintainers":[{"name":"haijindev","email":"haijin.development@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-snapshot_1.0.6_1609531122007_0.8947684797899056"},"_hasShrinkwrap":false},"1.0.7":{"name":"o-snapshot","version":"1.0.7","description":"Objects serializer for NodeJS","main":"index.js","scripts":{"clean":"rm -rf node_modules && rm -f package-lock.json","test":"npx mocha --config ./utilities-config/.mocharc.json"},"keywords":["serialization"],"author":{"name":"Martin Rubi"},"license":"ISC","homepage":"http://o-programming-language.org","devDependencies":{"o-testing-toolbox":"^2.0.1","chai":"^4.2.0","eslint":"^7.16.0","eslint-config-standard":"^16.0.1","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.2.1","eslint-plugin-standard":"^5.0.0","mocha":"^7","nyc":"^15.1.0"},"dependencies":{"o-toolbox":"^4.0.0"},"gitHead":"e898b6655f863138b43f6aa9287bc1d2ba20a937","_id":"o-snapshot@1.0.7","_nodeVersion":"14.15.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-FU5sc5NqIq6yFU69ZDq8Nd016ecFMSplJpuzTmZi2rL1jroYZnoYwjd5UDCdHyOKY3ZWAUykK7Jbk78KsoWRcQ==","shasum":"adcdcb1734ad2d94e8a21588d5dc5d35c242eec9","tarball":"https://registry.npmjs.org/o-snapshot/-/o-snapshot-1.0.7.tgz","fileCount":26,"unpackedSize":76317,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf9MijCRA9TVsSAnZWagAAFZwP/RdazlZztBf95mX37QAX\nYwYchg/VjrTyKZZhV+FuxkQWgyBTJjfz8pIeBj0VTQlL1q60JGdO57ELpVcr\nH46doaQvDCABmSbZZkbDz0kT+CFBEpO/VeFjHuDKsQ9u7SM8Sl20DOHJswaj\n47VZ0/yngl0JhD5v+CkjPWBkD+9Vu/RmBsN1VZVHHL92B+lF9V7mDJXzGf/c\nC56y9jupcOABQWZ99Gm9nLSwkfJziIqczr2+WDQnBtwu9zg4innLrF9ZPJcT\nu1Tf0VOESCVOFgub7BoOQLhAa6u4njTXt/+R4HTCl7n8dmJdVaO6AvYRrL2j\nVeMjetCmbT1E6bX83e7UXTzcMNIeLLxnZfbduQxi+hKY66DPAdLeK614mQoH\nBa3V4t+Ztay09S2Jkk9/M/Sv7C/wXIqfXjUbM1/ryaesVYDtosq8PFzKd9nI\nogLs8sWBOEP26kX1ZDyq+LsbElrQqC/6eMlBKdwU+EglasO/6Xu4d+ahWf5+\nU4MwPYJagapjJykOeZILchauw+LfSXk1SNAwDeeIdJ2M9gWkpuqjMbH0X0Y8\nEsBpMp8TVQ/4adQJBeR//nXtwO0GWrHhcUiDDq5qRZvlfL4h/4qRJuAhGrlh\nrNpKQV/Q1xt6N+KZxfcZy03GkGa23cBRRIk/7a71FGaTHLl4NKPyBdBrj3xt\nrZOz\r\n=E6lE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC1B1QjtxYsv8aTlBcQ0ZtgdmWfSKBjSbK5U6KwMBhTFAiEA+jPjlUPG8RXFf6Kf98gSh1tTe0irKq7Xse4ZTZ0sYZg="}]},"_npmUser":{"name":"haijindev","email":"haijin.development@gmail.com"},"directories":{},"maintainers":[{"name":"haijindev","email":"haijin.development@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-snapshot_1.0.7_1609877666963_0.14833747809840436"},"_hasShrinkwrap":false},"2.0.0":{"name":"o-snapshot","version":"2.0.0","description":"Objects serializer, for NodeJS and JS","main":"index.js","scripts":{"examples":"npx checklist testsDirectory ./examples","test":"npx checklist"},"keywords":["serialization","in memory database","objects database","no-sql"],"author":{"name":"Martin Rubi"},"license":"ISC","homepage":"http://o-programming-language.org","devDependencies":{"eslint":"^7.29.0","eslint-config-standard":"^16.0.1","eslint-plugin-import":"^2.22.1","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^5.1.0","nyc":"^15.1.0","o-check-list":"^2.0.0"},"dependencies":{"o-toolbox":"^7.6.0"},"gitHead":"093d3e1f2d513d99cff0961f3b2ef751296742dc","_id":"o-snapshot@2.0.0","_nodeVersion":"14.15.4","_npmVersion":"6.14.10","dist":{"integrity":"sha512-QutKlO35GqoR5dSdLA5PK0Np5T8PeTcY29/9UIrPHqy34ds8Si6elxqk921LoIVOxAVF4ORRBtA+NgVJkK84Mg==","shasum":"7eaf7ea70f04b13bdf189df48530355948478945","tarball":"https://registry.npmjs.org/o-snapshot/-/o-snapshot-2.0.0.tgz","fileCount":57,"unpackedSize":125278,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgzi4JCRA9TVsSAnZWagAAtDgP/A0ZtT810ey4RvLPfhEU\n1wuTtV9KwcXXd3vskrZLdvIBUcq1YE9eDE2qgDQSYZGv7QzK8NN8vpQkDYpk\nqNzOA/NpJDLEnzU5qxUgpUhX3iU3yYL0DyGEuDaLs5VraioRAKE07tdkPR1F\ns2qy2J5WHZ/KKfO6nlIq/tjLhYC8mAJJID0o9+uysZaMxusiPjuwsU+udkrw\n0vJOwX70TFNFVbb+c7+QqxLaDxW/yfW/vYz40dKZ+vA/sxb/XZA6dMxlb7IG\n22DWbIk3D94IuObIFXH6RRCB9KwxtDeSCXAY7f8v6r4Lc8Lo4uYVZTO0z0qV\n1H0yUMdUYFYdIHk1altH0amxfe26xKgwDAfgMGZopTWGxfkZudIjNxao90sf\nl7vS0aPyl8zEy2/2qkUu7QgnD5sOjIaaRDjT9nqT3vyRaH3iBMG3ArOa68U4\nnkt30iux9j9qPpq9HFGDqJbU5pm3jdZVp8WkddMHUnOwDiMXDPqxcPCBcQg5\nMoMXd1YSUKtXyr0mzdkXouReA9NASq3WeARNKml4kIVu1Xc3sCkM4tXGKIOJ\n5/x/y8OUKIloL5kbnY2v3GF7IWZACiS3L6wYqk7en7J/seUDBddvxQPvSHvQ\nwO1mbEOzsb3kAuSgpnMUCtOl4GU9fwuh8OkQZcyypHpTZ11VrYQWnYX3Vq96\nipmv\r\n=018/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBSMhe6F8CidH/anzhUNbwC4to93Jlk0XxQ+VfXaoLYIAiBLG0tgS6cW1cTSzeW0dmkGgZV3cm2r81fyMdo+b1qTOg=="}]},"_npmUser":{"name":"haijindev","email":"haijin.development@gmail.com"},"directories":{},"maintainers":[{"name":"haijindev","email":"haijin.development@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-snapshot_2.0.0_1624124936865_0.25528837485436906"},"_hasShrinkwrap":false}},"time":{"created":"2020-09-30T10:56:07.602Z","1.0.0":"2020-09-30T10:56:07.768Z","modified":"2022-05-12T00:03:25.259Z","1.0.1":"2020-10-17T17:31:45.122Z","1.0.3":"2020-11-08T19:10:47.233Z","1.0.4":"2020-11-14T17:57:49.610Z","1.0.5":"2020-12-26T17:10:02.442Z","1.0.6":"2021-01-01T19:58:42.126Z","1.0.7":"2021-01-05T20:14:27.060Z","2.0.0":"2021-06-19T17:48:57.039Z"},"maintainers":[{"name":"haijindev","email":"haijin.development@gmail.com"}],"description":"Objects serializer, for NodeJS and JS","homepage":"http://o-programming-language.org","keywords":["serialization","in memory database","objects database","no-sql"],"author":{"name":"Martin Rubi"},"license":"ISC","readme":"# Snapshot\r\n\r\nObjects serializer, for NodeJS and JS\r\n\r\nAmong other features, `o-snapshot`\r\n\r\n- preserves the identity of serialized objects, after deserialization\r\n\r\n- preserves the class of serialized objects, after deserialization\r\n\r\n- gives the programmer complete control over which classes can be serialized, and which classes can't\r\n\r\n- gives the programmer complete control over which attributes to serialize, and how\r\n\r\n- supports a simple mechanism to upgrade a snapshot from a previous version, saved using a \r\n  different format\r\n\r\n- when used with classes, rather than plain Objects, the size of a serialized snapshot is an order\r\n  of magnitude below the size of the same snapshot in plain json\r\n\r\n- supports circular references\r\n\r\n- supports the serialization of object surrogates\r\n\r\n- runs on both Node >= v10, and browsers >= ES9\r\n\r\nAdditionaly, used as an in-memory objects database, whether in browser or Node.js, `o-snapshot`\r\n\r\n  - supports in-memory, atomic transactions\r\n\r\n  - implements an extremely naive, and a bit of not entirely correct, garbage collection strategy\r\n\r\n## Installation\r\n\r\n```\r\nnpm install o-snapshot\r\n```\r\n\r\n## Documentation\r\n\r\n## Basic usage\r\n\r\n`o-snapshot` has 2 main concepts\r\n\r\nFirst one, it's the `Serializer`\r\n\r\nA `Serializer` converts back and forth between instances of a single class, and json objects\r\n\r\nSecond one, it's the `ObjectsDatabase`\r\n\r\n`ObjectsDatabase` takes an object, finds a serializer for it, and serializes or deserializes it, along with the objects it references\r\n\r\n`InMemoryDatabase` is a concrete `ObjectsDatabase` \r\n\r\n## Example of use\r\n\r\nYou can browse the complete, functional example, in [here](./examples)\r\n\r\nSay there are 2 classes\r\n\r\n```javascript\r\nconst { SequentialCollection } = require('o-toolbox')\r\n\r\nclass Book {\r\n  constructor({ author, title, isbn }) {\r\n    this.author = author\r\n    this.title = title\r\n    this.isbn = isbn\r\n    this.editions = new SequentialCollection()\r\n  }\r\n\r\n  addBookEdition({ bookEdition }) {\r\n    bookEdition._setBook({ book: this })\r\n\r\n    this.editions.add( bookEdition )\r\n  }\r\n\r\n  addAllBookEditions({ bookEditions }) {\r\n    bookEditions.forEach( (bookEdition) => {\r\n      this.addBookEdition({ bookEdition })\r\n    })\r\n  }\r\n\r\n  getAuthor() {\r\n    return this.author\r\n  }\r\n\r\n  getAllEditions() {\r\n    return this.editions.copy()\r\n  }\r\n\r\n  getIsbn() {\r\n    return this.isbn\r\n  }\r\n\r\n  getTitle() {\r\n    return this.title\r\n  }\r\n}\r\n\r\nmodule.exports = Book\r\n```\r\n\r\nand\r\n\r\n```javascript\r\nconst { SequentialCollection } = require('o-toolbox')\r\n\r\nclass BookEdition {\r\n  constructor({ publisher, dateOfPublishing, numberOfPages }) {\r\n    this.publisher = publisher\r\n    this.dateOfPublishing = dateOfPublishing\r\n    this.numberOfPages = numberOfPages\r\n    this.copies = new SequentialCollection()\r\n    this.book = null\r\n  }\r\n\r\n  addBookCopy({ bookCopy }) {\r\n    bookCopy._setBookEdition({ bookEdition: this })\r\n\r\n    this.copies.add( bookCopy )\r\n  }\r\n\r\n  addAllBookCopies({ bookCopies }) {\r\n    bookCopies.forEach( (bookCopy) => {\r\n      this.addBookCopy({ bookCopy })\r\n    })\r\n  }\r\n\r\n  getAuthor() {\r\n    return this.book.getAuthor()\r\n  }\r\n\r\n  _setBook({ book }) {\r\n    this.book = book\r\n  }\r\n}\r\n\r\nmodule.exports = BookEdition\r\n```\r\n\r\nCreate a serializer for `Book` objects\r\n\r\n```javascript\r\nconst Book = require('../models/Book')\r\n\r\nclass BookSerializer {\r\n  getClass () {\r\n    return Book\r\n  }\r\n\r\n  getClassId () {\r\n    return 'Book'\r\n  }\r\n\r\n  getClassVersion () {\r\n    return 1\r\n  }\r\n\r\n  serialize ( book ) {\r\n    const { title, author, isbn, editions } = book\r\n\r\n    return [ title, author, isbn, editions ]\r\n  }\r\n\r\n  deserialize ({ attributes }) {\r\n    const [ title, author, isbn, editions ] = attributes\r\n\r\n    const book = new Book({ title, author, isbn })\r\n\r\n    book.addAllBookEditions({ bookEditions: editions })\r\n\r\n    return book\r\n  }\r\n}\r\n\r\nmodule.exports = BookSerializer\r\n```\r\n\r\nand a serializer for `BookEdition` objects\r\n\r\n```javascript\r\nconst BookEdition = require('../models/BookEdition')\r\n\r\nclass BookEditionSerializer {\r\n  getClass () {\r\n    return BookEdition\r\n  }\r\n\r\n  getClassId () {\r\n    return 'BookEdition'\r\n  }\r\n\r\n  getClassVersion () {\r\n    return 1\r\n  }\r\n\r\n  serialize ( bookEdition ) {\r\n    const { publisher, dateOfPublishing, numberOfPages, copies } = bookEdition\r\n \r\n    return [ publisher, dateOfPublishing, numberOfPages, copies ]\r\n  }\r\n\r\n  deserialize ({ attributes }) {\r\n    const [ publisher, dateOfPublishing, numberOfPages, copies ] = attributes\r\n\r\n    const bookEdition = new BookEdition({ publisher, dateOfPublishing, numberOfPages })\r\n    bookEdition.addAllBookCopies({ bookCopies: copies })\r\n\r\n    return bookEdition\r\n  }\r\n}\r\n\r\nmodule.exports = BookEditionSerializer\r\n```\r\n\r\n## Serializers\r\n\r\nA `Serializer` can be any object, as long as it defines the methods\r\n\r\n**getClass**\r\n\r\nReturns the class of the objects it serializes\r\n\r\n**getClassId**\r\n\r\nReturns the name of the class it serializes, or any other unique id\r\n\r\nIn a regular context, it may seem redundant to have two different methods to get a class, and its name\r\n\r\nThere are use cases where it's needed to, though\r\n\r\nSuch a case is when the serializer is evaluated in an environment that has no access to class names, like a deployment with its source code minified or obfuscated. That's a common case in Single Page Applications\r\n\r\nAnother one, is when a refactor changes the class name, but the application should preserve backwards compatibility with objects already serialized\r\n\r\n**getClassVersion**\r\n\r\nReturns the current version of the class\r\n\r\nThe class version is an integer, greater or equal than 1\r\n\r\nLater in this document, there's an example that shows what to use the class version for\r\n\r\n**serialize**\r\n\r\nTakes an instance of the class, and returns either an array, or a json object, with the attributes to serialize\r\n\r\n`serialize()` is a regular method, and can get the attributes using the object public interface. It does not need to know the object internals\r\n\r\nIt's possible to write serializers for objects defined in a third party library\r\n\r\n`serialize()` can add, change or remove any attribute of the object being serialized\r\n\r\nThe attributes returned by `.serialize()` might include values, like Number and String, null, undefined, and instances of other classes\r\n\r\n`o-snapshot` takes care of serializing referred instances too, if they have a serializer\r\n\r\n**deserialize**\r\n\r\nIt does the opposite to the `serialize` method\r\n\r\nIt takes the serialized attributes, and creates and returns an instance of the class\r\n\r\nThe attributes it receives are already deserialized to their class instance form\r\n\r\n`deserialize()` also takes a second parameter, the serialized class version, to upgrade the serialized object if it needs to\r\n\r\n## InMemoryDatabase\r\n\r\nThe entry point to an object serialization, or deserialization, is an `InMemoryDatabase`\r\n\r\nBefore using it, configure it with the serializers of choice:\r\n\r\n```javascript\r\nconst { InMemoryDatabase } = require('o-snapshot')\r\n\r\nconst inMemoryDatabase = new InMemoryDatabase()\r\n      .register({ serializer: new BookSerializer() })\r\n      .register({ serializer: new BookEditionSerializer() })\r\n      .register({ serializer: new SequentialCollectionSerializer() })\r\n```\r\n\r\nThen, add an object, and take a snapshot\r\n\r\n```javascript\r\nconst book = new Book({\r\n  title: 'Hamlet',\r\n  author: 'William Shakespeare',\r\n  isbn: '112233'\r\n})\r\n\r\nconst snapshot = inMemoryDatabase\r\n      .setAt({ key: 'root', value: book })\r\n      .takeSnapshot()\r\n```\r\n\r\nIt's possible to serialize more than one root object in the same snapshot, if it makes sense for the program\r\n\r\n```javascript\r\nconst snapshot = inMemoryDatabase\r\n      .setAt({ key: 'users', value: users })\r\n      .setAt({ key: 'products', value: products })\r\n      .takeSnapshot()\r\n```\r\n\r\nTo restore back a snapshot\r\n\r\n```javascript\r\ninMemoryDatabase.restoreSnapshot({ snapshot })\r\n\r\nconst book = inMemoryDatabase.at({ key: 'root' })\r\n```\r\n\r\n## How does it work\r\n\r\nWhen `InMemoryDatabase` adds a `Book` object, it looks for the object class (specifically, it looks for the `object.constructor`) in its registered serializers\r\n\r\nIf it finds one, it calls `serializer.serialize( object )`, to get the list of the attributes to serialize\r\n\r\nIt does the same with each one of the returned attributes\r\n\r\nOnce it iterates through all the reference graph, starting at the given object, it flattens the objects graph to an array of json attributes\r\n\r\n## Objects identity\r\n\r\nThe identity of each object is preserved after its deserialization\r\n\r\nSerialized objects don't need to implement an identity surrogate. It uses the identity of the object in memory\r\n\r\n\r\nE.g.\r\n\r\nBefore the serialization of\r\n\r\n```javascript\r\nconst book = new Book({\r\n  title: 'Hamlet',\r\n  author: 'William Shakespeare',\r\n  isbn: '112233'\r\n})\r\n\r\nconst books = [ book, book, book ]\r\n```\r\n\r\nArray `books` contains 3 occurrences of the identical object. Each element in the array points to the same object, `book`\r\n\r\nAfter its serialization\r\n\r\n```javascript\r\nconst { InMemoryDatabase } = require('o-snapshot')\r\n\r\nconst inMemoryDatabase = new InMemoryDatabase()\r\n      .register({ serializer: new BookSerializer() })\r\n      .register({ serializer: new BookEditionSerializer() })\r\n      .register({ serializer: new SequentialCollectionSerializer() })\r\n\r\nconst snapshot = inMemoryDatabase\r\n      .setAt({ key: 'root', value: books })\r\n      .takeSnapshot()\r\n```\r\n\r\nand deserialization\r\n\r\n```javascript\r\nconst { InMemoryDatabase } = require('o-snapshot')\r\n\r\nconst inMemoryDatabase = new InMemoryDatabase()\r\n      .register({ serializer: new BookSerializer() })\r\n      .register({ serializer: new BookEditionSerializer() })\r\n      .register({ serializer: new SequentialCollectionSerializer() })\r\n\r\ninMemoryDatabase.restoreSnapshot({ snapshot })\r\n\r\nconst books = inMemoryDatabase.at({ key: 'root' })\r\n```\r\n\r\nthe identity of the objects is preserved, and the new `books` Array also contains 3 occurrences of a single object, rather than 3 equal objects with different identities\r\n\r\nDuring the serialization of a complex graph of objects, to preserve the invariant of the identity of objects may be significant. Otherwise, the program may have unexpected errors, like an object not emitting events as expected\r\n\r\nIn addition, it can reduce significantly the size of a snapshot, if it holds many refences to identical objects\r\n\r\nE.g, a snapshot of a collection of product orders\r\n\r\n```javascript\r\n{\r\n  orders : [\r\n    {\r\n      user,\r\n      products: [\r\n        { product }, ...\r\n      ]\r\n    },\r\n    ...\r\n  ]\r\n}\r\n```\r\n\r\nmay have multiple references to identical products and users\r\n\r\nWithin the snapshot, each object is serialized, with its attributes, only once\r\n\r\nReferences to other objects are serialized as `ObjectReference`s instead, using an Integer\r\n\r\n## Built-in serializers\r\n\r\nAlthough it's quite possible, and even quite simple, to make a serializer capable to serialize any object at all, rather than to require the programmer to declare each serializer explicitly, it proved to be a troubled design\r\n\r\nTo explicitly declare serializers makes the program more secure, more simple to debug, and more easy to understand\r\n\r\nIn addition, it allows to use different serializers, in different contexts, for the same classes, and features like class versioning, and surrogate references\r\n\r\nSome built-in types come with serializers out of the box\r\n\r\nObjects of type\r\n\r\n- undefined\r\n- null\r\n- String\r\n- Number\r\n- Array\r\n- Object\r\n- Boolean\r\n\r\ndon't need to declare a custom serializer\r\n\r\nAny other class, it does\r\n\r\nBuilt-in serializers can be overriden, as well\r\n\r\n## Surrogate references\r\n\r\nSay the application uses a global reference\r\n\r\n```javascript\r\n// global variable\r\nconst localClock = new Clock()\r\n\r\nuser.setClock( clock )\r\n\r\nconst snapshot = inMemoryDatabase\r\n  .setAt({ key: 'root', value: user })\r\n  .takeSnapshot()\r\n```\r\n\r\nThe restoration of the snapshot taken wouldn't preserve the identity of `localClock` object\r\n\r\nIt would create a new instance of `Clock`, different from the `localClock`\r\n\r\nTo preserve the reference to `localClock` object, the serializer must replace the reference by a surrogate object, and restore it back, at the time of its deserialization\r\n\r\n```javascript\r\nconst User = require('./User')\r\n\r\nclass UserSerializer {\r\n  getClass() {\r\n    return User\r\n  }\r\n\r\n  getClassId() {\r\n    return 'User'\r\n  }\r\n\r\n  getClassVersion() {\r\n    return 1\r\n  }\r\n\r\n  serialize(user) {\r\n    const clock = 'localClock'\r\n    return [ clock ]\r\n  }\r\n\r\n  deserialize({ attributes, classVersion }) {\r\n    const [ clock ] = attributes\r\n    const user = new User()\r\n\r\n    user.setClock( global.localClock )\r\n\r\n    return user\r\n  }  \r\n}\r\n\r\nmodule.exports = UserSerializer\r\n```\r\n\r\nThe same technique can be applied to serialize references to resources that may not persist between the time of object serialization, and the time of object deserialization, such as database connections, file handles, network sockets or GUI elements\r\n\r\nE.g.\r\n\r\n```javascript\r\nconst User = require('./User')\r\n\r\nclass UserSerializer {\r\n  constructor({ connectionPool }) {\r\n    this.connectionPool = connectionPool\r\n  }\r\n\r\n  getClass() {\r\n    return User\r\n  }\r\n\r\n  getClassId() {\r\n    return 'User'\r\n  }\r\n\r\n  getClassVersion() {\r\n    return 1\r\n  }\r\n\r\n  serialize( user ) {\r\n    const name = user.getName()\r\n    const databaseConfig = user.getDatabase().getConfig()\r\n\r\n    return [ name, databaseConfig ]\r\n  }\r\n\r\n  deserialize({ attributes, classVersion }) {\r\n    const [ name, databaseConfig ] = attributes\r\n\r\n    const user = new User({ name })\r\n    const databaseConnection = this.connectionPool.getDatabaseConnection( databaseConfig )\r\n\r\n    user.setDatabase(databaseConnection)\r\n\r\n    return user\r\n  }  \r\n}\r\n\r\nmodule.exports = UserSerializer\r\n```\r\n\r\n## Class versions and migrations\r\n\r\nOnce an application persists at least one object, a programmer needs to address a whole new set of problems\r\n\r\nSay there's a class\r\n\r\n```javascript\r\nclass User {\r\n  constructor({ lastName }) {\r\n    this.lastName = lastName\r\n  }\r\n\r\n  ...\r\n}\r\n```\r\n\r\nwith its serializer\r\n\r\n```javascript\r\nconst User = require('./User')\r\n\r\nclass UserSerializer {\r\n  getClass() {\r\n    return User\r\n  }\r\n\r\n  getClassId() {\r\n    return 'User'\r\n  }\r\n\r\n  getClassVersion() {\r\n    return 1\r\n  }\r\n\r\n  serialize( user ) {\r\n    const lastName = user.lastName\r\n\r\n    return { lastName }\r\n  }\r\n\r\n  deserialize({ attributes, classVersion }) {\r\n    const { lastName } = attributes\r\n\r\n    return new User({ lastName })\r\n  }  \r\n}\r\n\r\nmodule.exports = UserSerializer\r\n```\r\n\r\nA snapshot is taken at time t1\r\n\r\n```javascript\r\nconst snapshotAtTime1 = inMemoryDatabase\r\n  .setAt({ key: 'root', value: user })\r\n  .takeSnapshot()\r\n```\r\n\r\nthen, at time t2, a refactor is made to `User` class\r\n\r\n```javascript\r\nclass User {\r\n  constructor({ lastname }) {\r\n    this.lastname = lastname\r\n  }\r\n\r\n  ...\r\n}\r\n```\r\n\r\nEven it may not seem like that much of a change, the rename of the instance variable will make any snapshot of the `User` class taken before t2, to fail the next time it's restored\r\n\r\nIssues appear because the application, or the environment where the application runs, may change between the time at which the snapshot is taken, and the time at which the snapshot is restored\r\n\r\nSerializers use the `getClassVersion` method to deal with this kind of errors\r\n\r\nTo properly handle the upgrade, every time `User` class changes its attributes, the serializer also upgrades it's version number\r\n\r\n```javascript\r\nconst { ImportMethods } = require('o-toolbox')\r\nconst { SerializerVersionUpgrades } = require('o-snapshot')\r\nconst User = require('./User')\r\n\r\nclass UserSerializer {\r\n  getClass() {\r\n    return User\r\n  }\r\n\r\n  getClassId() {\r\n    return 'User'\r\n  }\r\n\r\n  getClassVersion() {\r\n    return 2            // <-- increased by 1 \r\n  }\r\n\r\n  serialize( user ) {\r\n    const lastname = user.lastname\r\n\r\n    return { lastname }\r\n  }\r\n\r\n  deserialize({ attributes, classVersion }) {\r\n    if ( classVersion === 1 ) {\r\n      const { lastName } = attributes\r\n      const lastname = lastName\r\n      return new User({ lastname })\r\n    }\r\n\r\n    const { lastname } = attributes\r\n\r\n    return new User({ lastname })\r\n  }\r\n}\r\n\r\nmodule.exports = UserSerializer\r\n```\r\n\r\nNote that `getClassVersion` increments its value by 1\r\n\r\n## Validations\r\n\r\nIt's a good idea to validate each attribute before each object serialization/deserialization\r\n\r\nIt may save a lot of debugging time\r\n\r\n`o-snapshot` does not include any validation utility\r\n\r\nAny assertions or validations library can be used within `serialize` and `deserialize` methods for that matter\r\n\r\nThe author of `o-snapshot`, that would be me, recomends [o-check-list](https://bitbucket.org/haijin-development/check-list), for it's simplicity, ease of use, and adaptability to different contexts, since it works in both Node.js >= 10, and browser regular JS >= ES9\r\n\r\n\r\n## DoMe commands\r\n\r\nDoMe commands are intended to be self-documented, please take a look at the files in `DoMe/forDevelopment/inWindows`, or in `DoMe/forDevelopment/inDocker`\r\n","readmeFilename":"README.md"}