HookMap.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const util = require("util");
  7. const defaultFactory = (key, hook) => hook;
  8. class HookMap {
  9. constructor(factory, name = undefined) {
  10. this._map = new Map();
  11. this.name = name;
  12. this._factory = factory;
  13. this._interceptors = [];
  14. }
  15. get(key) {
  16. return this._map.get(key);
  17. }
  18. for(key) {
  19. // Hot path: inline the map lookup to skip the `this.get(key)`
  20. // indirection. This gets hit on every hook access in consumers
  21. // like webpack.
  22. const map = this._map;
  23. const hook = map.get(key);
  24. if (hook !== undefined) {
  25. return hook;
  26. }
  27. let newHook = this._factory(key);
  28. const interceptors = this._interceptors;
  29. for (let i = 0; i < interceptors.length; i++) {
  30. newHook = interceptors[i].factory(key, newHook);
  31. }
  32. map.set(key, newHook);
  33. return newHook;
  34. }
  35. intercept(interceptor) {
  36. this._interceptors.push(
  37. Object.assign(
  38. {
  39. factory: defaultFactory
  40. },
  41. interceptor
  42. )
  43. );
  44. }
  45. }
  46. HookMap.prototype.tap = util.deprecate(function tap(key, options, fn) {
  47. return this.for(key).tap(options, fn);
  48. }, "HookMap#tap(key,…) is deprecated. Use HookMap#for(key).tap(…) instead.");
  49. HookMap.prototype.tapAsync = util.deprecate(function tapAsync(
  50. key,
  51. options,
  52. fn
  53. ) {
  54. return this.for(key).tapAsync(options, fn);
  55. }, "HookMap#tapAsync(key,…) is deprecated. Use HookMap#for(key).tapAsync(…) instead.");
  56. HookMap.prototype.tapPromise = util.deprecate(function tapPromise(
  57. key,
  58. options,
  59. fn
  60. ) {
  61. return this.for(key).tapPromise(options, fn);
  62. }, "HookMap#tapPromise(key,…) is deprecated. Use HookMap#for(key).tapPromise(…) instead.");
  63. module.exports = HookMap;