-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
codeManager.js
123 lines (99 loc) · 2.68 KB
/
codeManager.js
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
const BundleFileOutput = require("./BundleFileOutput");
const debug = require("debug")("Eleventy:Bundle");
class CodeManager {
constructor(name) {
this.name = name;
this.trimOnAdd = true;
this.reset();
this.transforms = [];
}
reset() {
this.pages = {};
}
static normalizeBuckets(bucket) {
if(Array.isArray(bucket)) {
return bucket;
} else if(typeof bucket === "string") {
return bucket.split(",");
}
return ["default"];
}
setTransforms(transforms) {
if(!Array.isArray(transforms)) {
throw new Error("Array expected to setTransforms");
}
this.transforms = transforms;
}
addToPage(pageUrl, code = [], bucket) {
if(!Array.isArray(code) && code) {
code = [code];
}
if(code.length === 0) {
return;
}
if(!this.pages[pageUrl]) {
this.pages[pageUrl] = {};
}
let buckets = CodeManager.normalizeBuckets(bucket);
for(let b of buckets) {
if(!this.pages[pageUrl][b]) {
this.pages[pageUrl][b] = new Set();
}
let content = code.map(entry => {
if(this.trimOnAdd) {
return entry.trim();
}
return entry;
}).join("\n");
debug("Adding %o to bundle %o for %o (bucket: %o)", content, this.name, pageUrl, b);
this.pages[pageUrl][b].add(content);
}
}
async runTransforms(str, pageData) {
for (let callback of this.transforms) {
str = await callback.call(
{
page: pageData
},
str
);
}
return str;
}
async getForPage(pageData, buckets) {
let url = pageData.url;
if(!this.pages[url]) {
debug("No bundle code found for %o on %o, %O", this.name, url, this.pages);
return "";
}
buckets = CodeManager.normalizeBuckets(buckets);
debug("Retrieving %o for %o (buckets: %o)", this.name, url, buckets);
let set = new Set();
for(let b of buckets) {
if(!this.pages[url][b]) {
// Just continue, if you retrieve code from a bucket that doesn’t exist or has no code, it will return an empty set
continue;
}
for(let entry of this.pages[url][b]) {
set.add(entry);
}
}
let bundleContent = Array.from(set).join("\n");
// returns promise
return this.runTransforms(bundleContent, pageData);
}
async writeBundle(pageData, buckets, options = {}) {
let url = pageData.url;
if(!this.pages[url]) {
debug("No bundle code found for %o on %o, %O", this.name, url, this.pages);
return "";
}
let { output, bundle, write } = options;
buckets = CodeManager.normalizeBuckets(buckets);
// TODO the bundle output URL might be useful in the transforms for sourcemaps
let content = await this.getForPage(pageData, buckets);
let writer = new BundleFileOutput(output, bundle);
return writer.writeBundle(content, this.name, write);
}
}
module.exports = CodeManager;