1 | import _ from 'underscore';
|
2 |
|
3 | import walk from './walk.js';
|
4 |
|
5 | const getAllFiles = build =>
|
6 | _.reduce(
|
7 | build.builds,
|
8 | (files, build) => ({ ...files, ...getAllFiles(build) }),
|
9 | build.files
|
10 | );
|
11 |
|
12 | const deleteFile = ({ build: { builds, files }, path }) => {
|
13 | delete files[path];
|
14 | for (const build of builds) deleteFile({ build, path });
|
15 | };
|
16 |
|
17 | const resolve = async ({ env, path, buildsSeen = {} }) => {
|
18 | if (buildsSeen[path]) return;
|
19 |
|
20 | buildsSeen[path] = true;
|
21 | const files = _.indexBy(await walk({ env, path }), 'path');
|
22 | const builds = _.compact(
|
23 | _.flatten(
|
24 | await Promise.all(
|
25 | _.map(files, file =>
|
26 | Promise.all(
|
27 | _.map(file.builds, path => resolve({ env, path, buildsSeen }))
|
28 | )
|
29 | )
|
30 | )
|
31 | )
|
32 | );
|
33 |
|
34 | const filesSeen = {};
|
35 | for (const build of builds) {
|
36 | for (const [path, file] of Object.entries(getAllFiles(build))) {
|
37 | if (files[path]) {
|
38 | deleteFile({ build, path });
|
39 | } else if (filesSeen[path]) {
|
40 | files[path] = file;
|
41 | deleteFile({ build: filesSeen[path], path });
|
42 | deleteFile({ build, path });
|
43 | delete filesSeen[path];
|
44 | } else {
|
45 | filesSeen[path] = build;
|
46 | }
|
47 | }
|
48 | }
|
49 |
|
50 | return { builds, files, path };
|
51 | };
|
52 |
|
53 | const setBuffers = ({ build, target }) => {
|
54 | const { builds, files } = build;
|
55 | delete build.files;
|
56 | for (const build of builds) setBuffers({ build, target });
|
57 | let size = 0;
|
58 | let buffers = [];
|
59 | build.buffers = [];
|
60 | for (const path in files) {
|
61 | const { buffer } = files[path];
|
62 | if (size && size + buffer.length > target.maxChunkSize) {
|
63 | build.buffers.push(Buffer.concat(buffers));
|
64 | size = 0;
|
65 | buffers = [];
|
66 | }
|
67 | size += buffer.length;
|
68 | buffers.push(buffer);
|
69 | }
|
70 | if (buffers.length) build.buffers.push(Buffer.concat(buffers));
|
71 | };
|
72 |
|
73 | export default async ({ env, path, target }) => {
|
74 | const build = await resolve({ env, path });
|
75 | setBuffers({ build, target });
|
76 | return build;
|
77 | };
|