source.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. /** @import { Source } from "webpack-sources" */
  7. /** @import Hash from "./Hash" */
  8. /** @type {WeakMap<Source, WeakMap<Source, boolean>>} */
  9. const equalityCache = new WeakMap();
  10. /**
  11. * Checks whether source equal true, when both sources are equal.
  12. * @param {Source} a a source
  13. * @param {Source} b another source
  14. * @returns {boolean} true, when both sources are equal
  15. */
  16. const _isSourceEqual = (a, b) => {
  17. // prefer .buffer(), it's called anyway during emit
  18. /** @type {Buffer | string} */
  19. let aSource = typeof a.buffer === "function" ? a.buffer() : a.source();
  20. /** @type {Buffer | string} */
  21. let bSource = typeof b.buffer === "function" ? b.buffer() : b.source();
  22. if (aSource === bSource) return true;
  23. if (typeof aSource === "string" && typeof bSource === "string") return false;
  24. if (!Buffer.isBuffer(aSource)) aSource = Buffer.from(aSource, "utf8");
  25. if (!Buffer.isBuffer(bSource)) bSource = Buffer.from(bSource, "utf8");
  26. return aSource.equals(bSource);
  27. };
  28. /**
  29. * Checks whether this object is source equal.
  30. * @param {Source} a a source
  31. * @param {Source} b another source
  32. * @returns {boolean} true, when both sources are equal
  33. */
  34. const isSourceEqual = (a, b) => {
  35. if (a === b) return true;
  36. const cache1 = equalityCache.get(a);
  37. if (cache1 !== undefined) {
  38. const result = cache1.get(b);
  39. if (result !== undefined) return result;
  40. }
  41. const result = _isSourceEqual(a, b);
  42. if (cache1 !== undefined) {
  43. cache1.set(b, result);
  44. } else {
  45. const map = new WeakMap();
  46. map.set(b, result);
  47. equalityCache.set(a, map);
  48. }
  49. const cache2 = equalityCache.get(b);
  50. if (cache2 !== undefined) {
  51. cache2.set(a, result);
  52. } else {
  53. const map = new WeakMap();
  54. map.set(a, result);
  55. equalityCache.set(b, map);
  56. }
  57. return result;
  58. };
  59. // TODO remove in webpack 6, this is protection against authors who directly use `webpack-sources` outdated version
  60. /**
  61. * Feeds the Source's content into a Hash without forcing a single
  62. * concatenated Buffer. Uses webpack-sources >= 3.4.0 `buffers()` when
  63. * available so `ConcatSource` can stream its children directly.
  64. * @param {Hash} hash hash to update
  65. * @param {Source} source source whose bytes are appended
  66. * @returns {void}
  67. */
  68. const updateHashFromSource = (hash, source) => {
  69. // TODO webpack 6: drop the `buffers` check, require webpack-sources >= 3.4
  70. // and call `source.buffers()` unconditionally.
  71. if (typeof source.buffers === "function") {
  72. for (const buf of source.buffers()) hash.update(buf);
  73. } else {
  74. hash.update(source.buffer());
  75. }
  76. };
  77. module.exports.isSourceEqual = isSourceEqual;
  78. module.exports.updateHashFromSource = updateHashFromSource;