PlainObjectSerializer.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. */
  4. "use strict";
  5. const cache = new WeakMap();
  6. class ObjectStructure {
  7. constructor() {
  8. this.keys = undefined;
  9. this.children = undefined;
  10. }
  11. getKeys(keys) {
  12. if (this.keys === undefined) this.keys = keys;
  13. return this.keys;
  14. }
  15. key(key) {
  16. if (this.children === undefined) this.children = new Map();
  17. const child = this.children.get(key);
  18. if (child !== undefined) return child;
  19. const newChild = new ObjectStructure();
  20. this.children.set(key, newChild);
  21. return newChild;
  22. }
  23. }
  24. const getCachedKeys = (keys, cacheAssoc) => {
  25. let root = cache.get(cacheAssoc);
  26. if (root === undefined) {
  27. root = new ObjectStructure();
  28. cache.set(cacheAssoc, root);
  29. }
  30. let current = root;
  31. for (const key of keys) {
  32. current = current.key(key);
  33. }
  34. return current.getKeys(keys);
  35. };
  36. class PlainObjectSerializer {
  37. serialize(obj, { write }) {
  38. const keys = Object.keys(obj);
  39. if (keys.length > 128) {
  40. // Objects with so many keys are unlikely to share structure
  41. // with other objects
  42. write(keys);
  43. for (const key of keys) {
  44. write(obj[key]);
  45. }
  46. } else if (keys.length > 1) {
  47. write(getCachedKeys(keys, write));
  48. for (const key of keys) {
  49. write(obj[key]);
  50. }
  51. } else if (keys.length === 1) {
  52. const key = keys[0];
  53. write(key);
  54. write(obj[key]);
  55. } else {
  56. write(null);
  57. }
  58. }
  59. deserialize({ read }) {
  60. const keys = read();
  61. const obj = {};
  62. if (Array.isArray(keys)) {
  63. for (const key of keys) {
  64. obj[key] = read();
  65. }
  66. } else if (keys !== null) {
  67. obj[keys] = read();
  68. }
  69. return obj;
  70. }
  71. }
  72. module.exports = PlainObjectSerializer;