summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/source-map-loader/utils/sourceMapRequests.js
blob: 49ceecd71a01c8aff2313a85fb49131caafdab61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */

"use strict";

const {
  generatedToOriginalId,
} = require("resource://devtools/client/shared/source-map-loader/utils/index.js");

const sourceMapRequests = new Map();

function clearSourceMaps() {
  for (const [, metadataPromise] of sourceMapRequests) {
    // The source-map module leaks memory unless `.destroy` is called on
    // the consumer instances when they are no longer being used.
    metadataPromise.then(
      metadata => {
        if (metadata) {
          metadata.map.destroy();
        }
      },
      // We don't want this to cause any unhandled rejection errors.
      () => {}
    );
  }

  sourceMapRequests.clear();
}

/**
 * For a given generated source, retrieve an object with many attributes:
 * @param {String} generatedSourceId
 *        The id of the generated source
 *
 * @return {Object} Meta data object with many attributes
 *     - map: The SourceMapConsumer or WasmRemap instance
 *     - urlsById Map of Original Source ID (string) to Source URL (string)
 *     - sources: Array of object with the two following attributes:
 *       - id: Original Source ID (string)
 *       - url: Original Source URL (string)
 */
function getSourceMapWithMetadata(generatedSourceId) {
  return sourceMapRequests.get(generatedSourceId);
}

/**
 * Retrieve the SourceMapConsumer or WasmRemap instance for a given generated source.
 *
 * @param {String} generatedSourceId
 *        The id of the generated source
 *
 * @return null | Promise<SourceMapConsumer | WasmRemap>
 */
function getSourceMap(generatedSourceId) {
  const request = getSourceMapWithMetadata(generatedSourceId);
  if (!request) {
    return null;
  }

  return request.then(result => result?.map);
}

/**
 * Record the SourceMapConsumer or WasmRemap instance for a given generated source.
 *
 * @param {String} generatedId
 *        The generated source ID.
 * @param {Promise<SourceMapConsumer or WasmRemap>} request
 *        A promise which should resolve to either a SourceMapConsume or WasmRemap instance.
 */
function setSourceMap(generatedId, request) {
  sourceMapRequests.set(
    generatedId,
    request.then(map => {
      if (!map || !map.sources) {
        return null;
      }

      const urlsById = new Map();
      const sources = [];
      let ignoreListUrls = [];

      if (map.x_google_ignoreList?.length) {
        ignoreListUrls = map.x_google_ignoreList.map(
          sourceIndex => map.sources[sourceIndex]
        );
      }

      for (const url of map.sources) {
        const id = generatedToOriginalId(generatedId, url);

        urlsById.set(id, url);
        sources.push({ id, url });
      }
      return { map, urlsById, sources, ignoreListUrls };
    })
  );
}

module.exports = {
  clearSourceMaps,
  getSourceMapWithMetadata,
  getSourceMap,
  setSourceMap,
};