serialization.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. */
  4. "use strict";
  5. const { DEFAULTS } = require("../config/defaults");
  6. const memoize = require("./memoize");
  7. /** @typedef {import("../serialization/BinaryMiddleware").MEASURE_END_OPERATION_TYPE} MEASURE_END_OPERATION */
  8. /** @typedef {import("../serialization/BinaryMiddleware").MEASURE_START_OPERATION_TYPE} MEASURE_START_OPERATION */
  9. /** @typedef {import("../util/Hash").HashFunction} HashFunction */
  10. /** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
  11. /**
  12. * Defines the serializer type used by this module.
  13. * @template D, S, C
  14. * @typedef {import("../serialization/Serializer")<D, S, C>} Serializer
  15. */
  16. const getBinaryMiddleware = memoize(() =>
  17. require("../serialization/BinaryMiddleware")
  18. );
  19. const getObjectMiddleware = memoize(() =>
  20. require("../serialization/ObjectMiddleware")
  21. );
  22. const getSingleItemMiddleware = memoize(() =>
  23. require("../serialization/SingleItemMiddleware")
  24. );
  25. const getSerializer = memoize(() => require("../serialization/Serializer"));
  26. const getSerializerMiddleware = memoize(() =>
  27. require("../serialization/SerializerMiddleware")
  28. );
  29. const getBinaryMiddlewareInstance = memoize(
  30. () => new (getBinaryMiddleware())()
  31. );
  32. const registerSerializers = memoize(() => {
  33. require("./registerExternalSerializer");
  34. // Load internal paths with a relative require
  35. // This allows bundling all internal serializers
  36. const internalSerializables = require("./internalSerializables");
  37. getObjectMiddleware().registerLoader(/^webpack\/lib\//, (req) => {
  38. const loader =
  39. internalSerializables[
  40. /** @type {keyof import("./internalSerializables")} */
  41. (req.slice("webpack/lib/".length))
  42. ];
  43. if (loader) {
  44. loader();
  45. } else {
  46. // eslint-disable-next-line no-console
  47. console.warn(`${req} not found in internalSerializables`);
  48. }
  49. return true;
  50. });
  51. });
  52. /**
  53. * @type {Serializer<EXPECTED_ANY, EXPECTED_ANY, EXPECTED_ANY>}
  54. */
  55. let buffersSerializer;
  56. // Expose serialization API
  57. module.exports = {
  58. get register() {
  59. return getObjectMiddleware().register;
  60. },
  61. get registerLoader() {
  62. return getObjectMiddleware().registerLoader;
  63. },
  64. get registerNotSerializable() {
  65. return getObjectMiddleware().registerNotSerializable;
  66. },
  67. get NOT_SERIALIZABLE() {
  68. return getObjectMiddleware().NOT_SERIALIZABLE;
  69. },
  70. /** @type {MEASURE_START_OPERATION} */
  71. get MEASURE_START_OPERATION() {
  72. return getBinaryMiddleware().MEASURE_START_OPERATION;
  73. },
  74. /** @type {MEASURE_END_OPERATION} */
  75. get MEASURE_END_OPERATION() {
  76. return getBinaryMiddleware().MEASURE_END_OPERATION;
  77. },
  78. get buffersSerializer() {
  79. if (buffersSerializer !== undefined) return buffersSerializer;
  80. registerSerializers();
  81. const Serializer = getSerializer();
  82. const binaryMiddleware = getBinaryMiddlewareInstance();
  83. const SerializerMiddleware = getSerializerMiddleware();
  84. const SingleItemMiddleware = getSingleItemMiddleware();
  85. return /** @type {Serializer<EXPECTED_ANY, EXPECTED_ANY, EXPECTED_ANY>} */ (
  86. buffersSerializer = new Serializer([
  87. new SingleItemMiddleware(),
  88. new (getObjectMiddleware())((context) => {
  89. if ("write" in context) {
  90. context.writeLazy = (value) => {
  91. context.write(
  92. SerializerMiddleware.createLazy(value, binaryMiddleware)
  93. );
  94. };
  95. }
  96. }, DEFAULTS.HASH_FUNCTION),
  97. binaryMiddleware
  98. ])
  99. );
  100. },
  101. /**
  102. * Creates a file serializer.
  103. * @template D, S, C
  104. * @param {IntermediateFileSystem} fs filesystem
  105. * @param {HashFunction} hashFunction hash function to use
  106. * @returns {Serializer<D, S, C>} file serializer
  107. */
  108. createFileSerializer: (fs, hashFunction) => {
  109. registerSerializers();
  110. const Serializer = getSerializer();
  111. const FileMiddleware = require("../serialization/FileMiddleware");
  112. const fileMiddleware = new FileMiddleware(fs, hashFunction);
  113. const binaryMiddleware = getBinaryMiddlewareInstance();
  114. const SerializerMiddleware = getSerializerMiddleware();
  115. const SingleItemMiddleware = getSingleItemMiddleware();
  116. return /** @type {Serializer<D, S, C>} */ (
  117. new Serializer([
  118. new SingleItemMiddleware(),
  119. new (getObjectMiddleware())((context) => {
  120. if ("write" in context) {
  121. context.writeLazy = (value) => {
  122. context.write(
  123. SerializerMiddleware.createLazy(value, binaryMiddleware)
  124. );
  125. };
  126. context.writeSeparate = (value, options) => {
  127. const lazy = SerializerMiddleware.createLazy(
  128. value,
  129. fileMiddleware,
  130. options
  131. );
  132. context.write(lazy);
  133. return lazy;
  134. };
  135. }
  136. }, hashFunction),
  137. binaryMiddleware,
  138. fileMiddleware
  139. ])
  140. );
  141. }
  142. };