租房小程序前端代码
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.

95 lines
4.4 KiB

3 months ago
  1. # structuredClone polyfill
  2. [![Downloads](https://img.shields.io/npm/dm/@ungap/structured-clone.svg)](https://www.npmjs.com/package/@ungap/structured-clone) [![build status](https://github.com/ungap/structured-clone/actions/workflows/node.js.yml/badge.svg)](https://github.com/ungap/structured-clone/actions) [![Coverage Status](https://coveralls.io/repos/github/ungap/structured-clone/badge.svg?branch=main)](https://coveralls.io/github/ungap/structured-clone?branch=main)
  3. An env agnostic serializer and deserializer with recursion ability and types beyond *JSON* from the *HTML* standard itself.
  4. * [Supported Types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types)
  5. * *not supported yet*: Blob, File, FileList, ImageBitmap, ImageData, and ArrayBuffer, but typed arrays are supported without major issues, but u/int8, u/int16, and u/int32 are the only safely suppored (right now).
  6. * *not possible to implement*: the `{transfer: []}` option can be passed but it's completely ignored.
  7. * [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone)
  8. * [Serializer](https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal)
  9. * [Deserializer](https://html.spec.whatwg.org/multipage/structured-data.html#structureddeserialize)
  10. Serialized values can be safely stringified as *JSON* too, and deserialization resurrect all values, even recursive, or more complex than what *JSON* allows.
  11. ### Examples
  12. Check the [100% test coverage](./test/index.js) to know even more.
  13. ```js
  14. // as default export
  15. import structuredClone from '@ungap/structured-clone';
  16. const cloned = structuredClone({any: 'serializable'});
  17. // as independent serializer/deserializer
  18. import {serialize, deserialize} from '@ungap/structured-clone';
  19. // the result can be stringified as JSON without issues
  20. // even if there is recursive data, bigint values,
  21. // typed arrays, and so on
  22. const serialized = serialize({any: 'serializable'});
  23. // the result will be a replica of the original object
  24. const deserialized = deserialize(serialized);
  25. ```
  26. #### Global Polyfill
  27. Note: Only monkey patch the global if needed. This polyfill works just fine as an explicit import: `import structuredClone from "@ungap/structured-clone"`
  28. ```js
  29. // Attach the polyfill as a Global function
  30. import structuredClone from "@ungap/structured-clone";
  31. if (!("structuredClone" in globalThis)) {
  32. globalThis.structuredClone = structuredClone;
  33. }
  34. // Or don't monkey patch
  35. import structuredClone from "@ungap/structured-clone"
  36. // Just use it in the file
  37. structuredClone()
  38. ```
  39. **Note**: Do not attach this module's default export directly to the global scope, whithout a conditional guard to detect a native implementation. In environments where there is a native global implementation of `structuredClone()` already, assignment to the global object will result in an infinite loop when `globalThis.structuredClone()` is called. See the example above for a safe way to provide the polyfill globally in your project.
  40. ### Extra Features
  41. There is no middle-ground between the structured clone algorithm and JSON:
  42. * JSON is more relaxed about incompatible values: it just ignores these
  43. * Structured clone is inflexible regarding incompatible values, yet it makes specialized instances impossible to reconstruct, plus it doesn't offer any helper, such as `toJSON()`, to make serialization possible, or better, with specific cases
  44. This module specialized `serialize` export offers, within the optional extra argument, a **lossy** property to avoid throwing when incompatible types are found down the road (function, symbol, ...), so that it is possible to send with less worrying about thrown errors.
  45. ```js
  46. // as default export
  47. import structuredClone from '@ungap/structured-clone';
  48. const cloned = structuredClone(
  49. {
  50. method() {
  51. // ignored, won't be cloned
  52. },
  53. special: Symbol('also ignored')
  54. },
  55. {
  56. // avoid throwing
  57. lossy: true,
  58. // avoid throwing *and* looks for toJSON
  59. json: true
  60. }
  61. );
  62. ```
  63. The behavior is the same found in *JSON* when it comes to *Array*, so that unsupported values will result as `null` placeholders instead.
  64. #### toJSON
  65. If `lossy` option is not enough, `json` will actually enforce `lossy` and also check for `toJSON` method when objects are parsed.
  66. Alternative, the `json` exports combines all features:
  67. ```js
  68. import {stringify, parse} from '@ungap/structured-clone/json';
  69. parse(stringify({any: 'serializable'}));
  70. ```