serializers.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.parseSerializedValue = parseSerializedValue;
  6. exports.serializeValue = serializeValue;
  7. /**
  8. * Copyright (c) Microsoft Corporation.
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. */
  22. function parseSerializedValue(value, handles) {
  23. return innerParseSerializedValue(value, handles, new Map());
  24. }
  25. function innerParseSerializedValue(value, handles, refs) {
  26. if (value.ref !== undefined) return refs.get(value.ref);
  27. if (value.n !== undefined) return value.n;
  28. if (value.s !== undefined) return value.s;
  29. if (value.b !== undefined) return value.b;
  30. if (value.v !== undefined) {
  31. if (value.v === 'undefined') return undefined;
  32. if (value.v === 'null') return null;
  33. if (value.v === 'NaN') return NaN;
  34. if (value.v === 'Infinity') return Infinity;
  35. if (value.v === '-Infinity') return -Infinity;
  36. if (value.v === '-0') return -0;
  37. }
  38. if (value.d !== undefined) return new Date(value.d);
  39. if (value.u !== undefined) return new URL(value.u);
  40. if (value.bi !== undefined) return BigInt(value.bi);
  41. if (value.r !== undefined) return new RegExp(value.r.p, value.r.f);
  42. if (value.a !== undefined) {
  43. const result = [];
  44. refs.set(value.id, result);
  45. for (const v of value.a) result.push(innerParseSerializedValue(v, handles, refs));
  46. return result;
  47. }
  48. if (value.o !== undefined) {
  49. const result = {};
  50. refs.set(value.id, result);
  51. for (const {
  52. k,
  53. v
  54. } of value.o) result[k] = innerParseSerializedValue(v, handles, refs);
  55. return result;
  56. }
  57. if (value.h !== undefined) {
  58. if (handles === undefined) throw new Error('Unexpected handle');
  59. return handles[value.h];
  60. }
  61. throw new Error('Unexpected value');
  62. }
  63. function serializeValue(value, handleSerializer) {
  64. return innerSerializeValue(value, handleSerializer, {
  65. lastId: 0,
  66. visited: new Map()
  67. });
  68. }
  69. function innerSerializeValue(value, handleSerializer, visitorInfo) {
  70. const handle = handleSerializer(value);
  71. if ('fallThrough' in handle) value = handle.fallThrough;else return handle;
  72. if (typeof value === 'symbol') return {
  73. v: 'undefined'
  74. };
  75. if (Object.is(value, undefined)) return {
  76. v: 'undefined'
  77. };
  78. if (Object.is(value, null)) return {
  79. v: 'null'
  80. };
  81. if (Object.is(value, NaN)) return {
  82. v: 'NaN'
  83. };
  84. if (Object.is(value, Infinity)) return {
  85. v: 'Infinity'
  86. };
  87. if (Object.is(value, -Infinity)) return {
  88. v: '-Infinity'
  89. };
  90. if (Object.is(value, -0)) return {
  91. v: '-0'
  92. };
  93. if (typeof value === 'boolean') return {
  94. b: value
  95. };
  96. if (typeof value === 'number') return {
  97. n: value
  98. };
  99. if (typeof value === 'string') return {
  100. s: value
  101. };
  102. if (typeof value === 'bigint') return {
  103. bi: value.toString()
  104. };
  105. if (isError(value)) {
  106. const error = value;
  107. if ('captureStackTrace' in globalThis.Error) {
  108. // v8
  109. return {
  110. s: error.stack || ''
  111. };
  112. }
  113. return {
  114. s: `${error.name}: ${error.message}\n${error.stack}`
  115. };
  116. }
  117. if (isDate(value)) return {
  118. d: value.toJSON()
  119. };
  120. if (isURL(value)) return {
  121. u: value.toJSON()
  122. };
  123. if (isRegExp(value)) return {
  124. r: {
  125. p: value.source,
  126. f: value.flags
  127. }
  128. };
  129. const id = visitorInfo.visited.get(value);
  130. if (id) return {
  131. ref: id
  132. };
  133. if (Array.isArray(value)) {
  134. const a = [];
  135. const id = ++visitorInfo.lastId;
  136. visitorInfo.visited.set(value, id);
  137. for (let i = 0; i < value.length; ++i) a.push(innerSerializeValue(value[i], handleSerializer, visitorInfo));
  138. return {
  139. a,
  140. id
  141. };
  142. }
  143. if (typeof value === 'object') {
  144. const o = [];
  145. const id = ++visitorInfo.lastId;
  146. visitorInfo.visited.set(value, id);
  147. for (const name of Object.keys(value)) o.push({
  148. k: name,
  149. v: innerSerializeValue(value[name], handleSerializer, visitorInfo)
  150. });
  151. return {
  152. o,
  153. id
  154. };
  155. }
  156. throw new Error('Unexpected value');
  157. }
  158. function isRegExp(obj) {
  159. return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
  160. }
  161. function isDate(obj) {
  162. return obj instanceof Date || Object.prototype.toString.call(obj) === '[object Date]';
  163. }
  164. function isURL(obj) {
  165. return obj instanceof URL || Object.prototype.toString.call(obj) === '[object URL]';
  166. }
  167. function isError(obj) {
  168. const proto = obj ? Object.getPrototypeOf(obj) : null;
  169. return obj instanceof Error || (proto === null || proto === void 0 ? void 0 : proto.name) === 'Error' || proto && isError(proto);
  170. }