toJS.js 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import { hasAnchor } from './identity.js';
  2. /**
  3. * Recursively convert any node or its contents to native JavaScript
  4. *
  5. * @param value - The input value
  6. * @param arg - If `value` defines a `toJSON()` method, use this
  7. * as its first argument
  8. * @param ctx - Conversion context, originally set in Document#toJS(). If
  9. * `{ keep: true }` is not set, output should be suitable for JSON
  10. * stringification.
  11. */
  12. function toJS(value, arg, ctx) {
  13. // eslint-disable-next-line @typescript-eslint/no-unsafe-return
  14. if (Array.isArray(value))
  15. return value.map((v, i) => toJS(v, String(i), ctx));
  16. if (value && typeof value.toJSON === 'function') {
  17. // eslint-disable-next-line @typescript-eslint/no-unsafe-call
  18. if (!ctx || !hasAnchor(value))
  19. return value.toJSON(arg, ctx);
  20. const data = { aliasCount: 0, count: 1, res: undefined };
  21. ctx.anchors.set(value, data);
  22. ctx.onCreate = res => {
  23. data.res = res;
  24. delete ctx.onCreate;
  25. };
  26. const res = value.toJSON(arg, ctx);
  27. if (ctx.onCreate)
  28. ctx.onCreate(res);
  29. return res;
  30. }
  31. if (typeof value === 'bigint' && !ctx?.keep)
  32. return Number(value);
  33. return value;
  34. }
  35. export { toJS };