serialization.js 4.4 KB

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