UNPKG

5.15 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5"use strict";
6
7const Source = require("./Source");
8
9const mapToBufferedMap = map => {
10 if (typeof map !== "object" || !map) return map;
11 const bufferedMap = Object.assign({}, map);
12 if (map.mappings) {
13 bufferedMap.mappings = Buffer.from(map.mappings, "utf-8");
14 }
15 if (map.sourcesContent) {
16 bufferedMap.sourcesContent = map.sourcesContent.map(
17 str => str && Buffer.from(str, "utf-8")
18 );
19 }
20 return bufferedMap;
21};
22
23const bufferedMapToMap = bufferedMap => {
24 if (typeof bufferedMap !== "object" || !bufferedMap) return bufferedMap;
25 const map = Object.assign({}, bufferedMap);
26 if (bufferedMap.mappings) {
27 map.mappings = bufferedMap.mappings.toString("utf-8");
28 }
29 if (bufferedMap.sourcesContent) {
30 map.sourcesContent = bufferedMap.sourcesContent.map(
31 buffer => buffer && buffer.toString("utf-8")
32 );
33 }
34 return map;
35};
36
37class CachedSource extends Source {
38 constructor(source, cachedData) {
39 super();
40 this._source = source;
41 this._cachedSourceType = cachedData ? cachedData.source : undefined;
42 this._cachedSource = undefined;
43 this._cachedBuffer = cachedData ? cachedData.buffer : undefined;
44 this._cachedSize = cachedData ? cachedData.size : undefined;
45 this._cachedMaps = cachedData ? cachedData.maps : new Map();
46 }
47
48 getCachedData() {
49 // We don't want to cache strings
50 // So if we have a caches sources
51 // create a buffer from it and only store
52 // if it was a Buffer or string
53 if (this._cachedSource) {
54 this.buffer();
55 }
56 const bufferedMaps = new Map();
57 for (const pair of this._cachedMaps) {
58 if (pair[1].bufferedMap === undefined) {
59 pair[1].bufferedMap = mapToBufferedMap(pair[1].map);
60 }
61 bufferedMaps.set(pair[0], {
62 map: undefined,
63 bufferedMap: pair[1].bufferedMap
64 });
65 }
66 return {
67 buffer: this._cachedBuffer,
68 source:
69 this._cachedSourceType !== undefined
70 ? this._cachedSourceType
71 : typeof this._cachedSource === "string"
72 ? true
73 : Buffer.isBuffer(this._cachedSource)
74 ? false
75 : undefined,
76 size: this._cachedSize,
77 maps: bufferedMaps
78 };
79 }
80
81 originalLazy() {
82 return this._source;
83 }
84
85 original() {
86 if (typeof this._source === "function") this._source = this._source();
87 return this._source;
88 }
89
90 source() {
91 if (this._cachedSource !== undefined) return this._cachedSource;
92 if (this._cachedBuffer && this._cachedSourceType !== undefined) {
93 return (this._cachedSource = this._cachedSourceType
94 ? this._cachedBuffer.toString("utf-8")
95 : this._cachedBuffer);
96 } else {
97 return (this._cachedSource = this.original().source());
98 }
99 }
100
101 buffer() {
102 if (typeof this._cachedBuffer !== "undefined") return this._cachedBuffer;
103 if (typeof this._cachedSource !== "undefined") {
104 if (Buffer.isBuffer(this._cachedSource)) {
105 return (this._cachedBuffer = this._cachedSource);
106 }
107 return (this._cachedBuffer = Buffer.from(this._cachedSource, "utf-8"));
108 }
109 if (typeof this.original().buffer === "function") {
110 return (this._cachedBuffer = this.original().buffer());
111 }
112 const bufferOrString = this.source();
113 if (Buffer.isBuffer(bufferOrString)) {
114 return (this._cachedBuffer = bufferOrString);
115 }
116 return (this._cachedBuffer = Buffer.from(bufferOrString, "utf-8"));
117 }
118
119 size() {
120 if (typeof this._cachedSize !== "undefined") return this._cachedSize;
121 if (typeof this._cachedSource !== "undefined") {
122 return (this._cachedSize = Buffer.byteLength(this._cachedSource));
123 }
124 if (typeof this._cachedBuffer !== "undefined") {
125 return (this._cachedSize = this._cachedBuffer.length);
126 }
127 return (this._cachedSize = this.original().size());
128 }
129
130 sourceAndMap(options) {
131 const key = options ? JSON.stringify(options) : "{}";
132 let cacheEntry = this._cachedMaps.get(key);
133 if (cacheEntry && cacheEntry.map === undefined) {
134 cacheEntry.map = bufferedMapToMap(cacheEntry.bufferedMap);
135 }
136 if (typeof this._cachedSource !== "undefined") {
137 if (cacheEntry === undefined) {
138 const map = this.original().map(options);
139 this._cachedMaps.set(key, { map, bufferedMap: undefined });
140 return {
141 source: this._cachedSource,
142 map
143 };
144 } else {
145 return {
146 source: this._cachedSource,
147 map: cacheEntry.map
148 };
149 }
150 } else if (cacheEntry !== undefined) {
151 return {
152 source: (this._cachedSource = this.original().source()),
153 map: cacheEntry.map
154 };
155 } else {
156 const result = this.original().sourceAndMap(options);
157 this._cachedSource = result.source;
158 this._cachedMaps.set(key, { map: result.map, bufferedMap: undefined });
159 return result;
160 }
161 }
162
163 map(options) {
164 const key = options ? JSON.stringify(options) : "{}";
165 let cacheEntry = this._cachedMaps.get(key);
166 if (cacheEntry !== undefined) {
167 if (cacheEntry.map === undefined) {
168 cacheEntry.map = bufferedMapToMap(cacheEntry.bufferedMap);
169 }
170 return cacheEntry.map;
171 }
172 const map = this.original().map(options);
173 this._cachedMaps.set(key, { map, bufferedMap: undefined });
174 return map;
175 }
176
177 updateHash(hash) {
178 this.original().updateHash(hash);
179 }
180}
181
182module.exports = CachedSource;