提交学习笔记专用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
3.8 KiB

  1. import { ClassRegistry } from './class-registry.js';
  2. import { Registry } from './registry.js';
  3. import { CustomTransformerRegistry, } from './custom-transformer-registry.js';
  4. import { applyReferentialEqualityAnnotations, applyValueAnnotations, generateReferentialEqualityAnnotations, walker, } from './plainer.js';
  5. import { copy } from 'copy-anything';
  6. export default class SuperJSON {
  7. /**
  8. * @param dedupeReferentialEqualities If true, SuperJSON will make sure only one instance of referentially equal objects are serialized and the rest are replaced with `null`.
  9. */
  10. constructor({ dedupe = false, } = {}) {
  11. this.classRegistry = new ClassRegistry();
  12. this.symbolRegistry = new Registry(s => s.description ?? '');
  13. this.customTransformerRegistry = new CustomTransformerRegistry();
  14. this.allowedErrorProps = [];
  15. this.dedupe = dedupe;
  16. }
  17. serialize(object) {
  18. const identities = new Map();
  19. const output = walker(object, identities, this, this.dedupe);
  20. const res = {
  21. json: output.transformedValue,
  22. };
  23. if (output.annotations) {
  24. res.meta = {
  25. ...res.meta,
  26. values: output.annotations,
  27. };
  28. }
  29. const equalityAnnotations = generateReferentialEqualityAnnotations(identities, this.dedupe);
  30. if (equalityAnnotations) {
  31. res.meta = {
  32. ...res.meta,
  33. referentialEqualities: equalityAnnotations,
  34. };
  35. }
  36. if (res.meta)
  37. res.meta.v = 1;
  38. return res;
  39. }
  40. deserialize(payload, options) {
  41. const { json, meta } = payload;
  42. let result = options?.inPlace ? json : copy(json);
  43. if (meta?.values) {
  44. result = applyValueAnnotations(result, meta.values, meta.v ?? 0, this);
  45. }
  46. if (meta?.referentialEqualities) {
  47. result = applyReferentialEqualityAnnotations(result, meta.referentialEqualities, meta.v ?? 0);
  48. }
  49. return result;
  50. }
  51. stringify(object) {
  52. return JSON.stringify(this.serialize(object));
  53. }
  54. parse(string) {
  55. return this.deserialize(JSON.parse(string), { inPlace: true });
  56. }
  57. registerClass(v, options) {
  58. this.classRegistry.register(v, options);
  59. }
  60. registerSymbol(v, identifier) {
  61. this.symbolRegistry.register(v, identifier);
  62. }
  63. registerCustom(transformer, name) {
  64. this.customTransformerRegistry.register({
  65. name,
  66. ...transformer,
  67. });
  68. }
  69. allowErrorProps(...props) {
  70. this.allowedErrorProps.push(...props);
  71. }
  72. }
  73. SuperJSON.defaultInstance = new SuperJSON();
  74. SuperJSON.serialize = SuperJSON.defaultInstance.serialize.bind(SuperJSON.defaultInstance);
  75. SuperJSON.deserialize = SuperJSON.defaultInstance.deserialize.bind(SuperJSON.defaultInstance);
  76. SuperJSON.stringify = SuperJSON.defaultInstance.stringify.bind(SuperJSON.defaultInstance);
  77. SuperJSON.parse = SuperJSON.defaultInstance.parse.bind(SuperJSON.defaultInstance);
  78. SuperJSON.registerClass = SuperJSON.defaultInstance.registerClass.bind(SuperJSON.defaultInstance);
  79. SuperJSON.registerSymbol = SuperJSON.defaultInstance.registerSymbol.bind(SuperJSON.defaultInstance);
  80. SuperJSON.registerCustom = SuperJSON.defaultInstance.registerCustom.bind(SuperJSON.defaultInstance);
  81. SuperJSON.allowErrorProps = SuperJSON.defaultInstance.allowErrorProps.bind(SuperJSON.defaultInstance);
  82. export { SuperJSON };
  83. export const serialize = SuperJSON.serialize;
  84. export const deserialize = SuperJSON.deserialize;
  85. export const stringify = SuperJSON.stringify;
  86. export const parse = SuperJSON.parse;
  87. export const registerClass = SuperJSON.registerClass;
  88. export const registerCustom = SuperJSON.registerCustom;
  89. export const registerSymbol = SuperJSON.registerSymbol;
  90. export const allowErrorProps = SuperJSON.allowErrorProps;
  91. //# sourceMappingURL=index.js.map