index.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. /** @typedef {import("./CachedSource").CachedData} CachedData */
  7. /** @typedef {import("./CompatSource").SourceLike} SourceLike */
  8. /** @typedef {import("./ConcatSource").Child} ConcatSourceChild */
  9. /** @typedef {import("./ReplaceSource").Replacement} Replacement */
  10. /** @typedef {import("./Source").Hash} Hash */
  11. /** @typedef {import("./Source").MapOptions} MapOptions */
  12. /** @typedef {import("./Source").RawSourceMap} RawSourceMap */
  13. /** @typedef {import("./Source").SourceAndMap} SourceAndMap */
  14. /** @typedef {import("./Source").SourceValue} SourceValue */
  15. /** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */
  16. /** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */
  17. /** @typedef {import("./helpers/streamChunks").OnName} OnName */
  18. /** @typedef {import("./helpers/streamChunks").OnSource} OnSource */
  19. /** @typedef {import("./helpers/streamChunks").Options} StreamChunksOptions */
  20. // eslint-disable-next-line valid-jsdoc
  21. /**
  22. * @template T
  23. * @param {() => T} fn memorized function
  24. * @returns {() => T} new function
  25. */
  26. const memoize = (fn) => {
  27. let cache = false;
  28. /** @type {T | undefined} */
  29. let result;
  30. return () => {
  31. if (cache) {
  32. return /** @type {T} */ (result);
  33. }
  34. result = fn();
  35. cache = true;
  36. // Allow to clean up memory for fn
  37. // and all dependent resources
  38. /** @type {(() => T) | undefined} */
  39. (fn) = undefined;
  40. return /** @type {T} */ (result);
  41. };
  42. };
  43. // eslint-disable-next-line valid-jsdoc
  44. /**
  45. * @template A
  46. * @template B
  47. * @param {A} obj input a
  48. * @param {B} exports input b
  49. * @returns {A & B} merged
  50. */
  51. const mergeExports = (obj, exports) => {
  52. const descriptors = Object.getOwnPropertyDescriptors(exports);
  53. for (const name of Object.keys(descriptors)) {
  54. const descriptor = descriptors[name];
  55. if (descriptor.get) {
  56. const fn = descriptor.get;
  57. Object.defineProperty(obj, name, {
  58. configurable: false,
  59. enumerable: true,
  60. get: memoize(fn)
  61. });
  62. } else if (typeof descriptor.value === "object") {
  63. Object.defineProperty(obj, name, {
  64. configurable: false,
  65. enumerable: true,
  66. writable: false,
  67. value: mergeExports({}, descriptor.value)
  68. });
  69. } else {
  70. throw new Error(
  71. "Exposed values must be either a getter or an nested object"
  72. );
  73. }
  74. }
  75. return /** @type {A & B} */ (Object.freeze(obj));
  76. };
  77. module.exports = mergeExports(
  78. {},
  79. {
  80. get Source() {
  81. return require("./Source");
  82. },
  83. get RawSource() {
  84. return require("./RawSource");
  85. },
  86. get OriginalSource() {
  87. return require("./OriginalSource");
  88. },
  89. get SourceMapSource() {
  90. return require("./SourceMapSource");
  91. },
  92. get CachedSource() {
  93. return require("./CachedSource");
  94. },
  95. get ConcatSource() {
  96. return require("./ConcatSource");
  97. },
  98. get ReplaceSource() {
  99. return require("./ReplaceSource");
  100. },
  101. get PrefixSource() {
  102. return require("./PrefixSource");
  103. },
  104. get SizeOnlySource() {
  105. return require("./SizeOnlySource");
  106. },
  107. get CompatSource() {
  108. return require("./CompatSource");
  109. },
  110. util: {
  111. get stringBufferUtils() {
  112. return require("./helpers/stringBufferUtils");
  113. }
  114. }
  115. }
  116. );