187 lines
6.8 KiB
JavaScript
187 lines
6.8 KiB
JavaScript
import svelte from 'rollup-plugin-svelte';
|
|
import image from '@rollup/plugin-image';
|
|
import resolve from '@rollup/plugin-node-resolve';
|
|
import terser from "@rollup/plugin-terser";
|
|
import postcss from 'rollup-plugin-postcss'
|
|
import htmlTemplate from 'rollup-plugin-generate-html-template';
|
|
import { readFile, writeFile } from 'fs';
|
|
import { basename } from 'path';
|
|
import { promisify } from 'util';
|
|
import zlib from 'node:zlib';
|
|
import { VERSION, } from 'rollup';
|
|
import { pascalCase } from "pascal-case";
|
|
import mime from 'mime';
|
|
|
|
function hexdump(buffer) {
|
|
let lines = [];
|
|
|
|
for (let i = 0; i < buffer.length; i += 16) {
|
|
let block = buffer.slice(i, i + 16); // cut buffer into blocks of 16
|
|
let hexArray = [];
|
|
|
|
for (let value of block) {
|
|
hexArray.push("0x" + value.toString(16).padStart(2, "0"));
|
|
}
|
|
|
|
let hexString = hexArray.join(", ");
|
|
let line = ` ${hexString}`;
|
|
lines.push(line);
|
|
}
|
|
|
|
return lines.join(",\n");
|
|
}
|
|
|
|
function cppCompressed(input, fileName, contentType) {
|
|
return new Promise((resolve, reject) => zlib.gzip(input, { level: zlib.constants.Z_BEST_COMPRESSION }, function (error, result) {
|
|
if (error) {
|
|
reject(err);
|
|
}
|
|
|
|
console.info(fileName + " compressed " + result.length + " bytes");
|
|
const array = hexdump(result);
|
|
const src = `/*
|
|
* Binary array for the Web UI.
|
|
* Gzip is used for smaller size and improved speeds.
|
|
*/
|
|
|
|
// Autogenerated do not edit!!
|
|
const uint16_t ${fileName.replace(".","_").toUpperCase()}_L = ${result.length};
|
|
const uint8_t ${fileName.replace(".","_").toUpperCase()}[] PROGMEM = {
|
|
${array}
|
|
};
|
|
|
|
void serve${pascalCase(fileName)}(AsyncWebServerRequest* request) {
|
|
AsyncWebServerResponse *response = request->beginResponse_P(200, "${contentType || mime.getType(fileName)}", ${fileName.replace(".","_").toUpperCase()}, ${fileName.replace(".","_").toUpperCase()}_L);
|
|
response->addHeader(F("Content-Encoding"), "gzip");
|
|
request->send(response);
|
|
}
|
|
`;
|
|
resolve(src);
|
|
}));
|
|
}
|
|
|
|
const isFunction = (arg) => typeof arg === 'function';
|
|
const isRegExp = (arg) => Object.prototype.toString.call(arg) === '[object RegExp]';
|
|
const readFilePromise = promisify(readFile);
|
|
const writeFilePromise = promisify(writeFile);
|
|
|
|
function isOutputChunk(file) {
|
|
return typeof file.code === 'string';
|
|
}
|
|
|
|
function getOutputFileContent(outputFileName, outputFile, outputOptions) {
|
|
if (isOutputChunk(outputFile)) {
|
|
let source;
|
|
source = outputFile.code;
|
|
if (outputOptions.sourcemap && outputFile.map) {
|
|
const url = outputOptions.sourcemap === 'inline'
|
|
? outputFile.map.toUrl()
|
|
: `${basename(outputFileName)}.map`;
|
|
source += `//# source` + `MappingURL=${url}\n`;
|
|
}
|
|
return source;
|
|
}
|
|
else {
|
|
return typeof outputFile.source === 'string'
|
|
? outputFile.source
|
|
: // just to be sure, as it is typed string | Uint8Array in rollup 2.0.0
|
|
Buffer.from(outputFile.source);
|
|
}
|
|
}
|
|
|
|
function cpp(options = {}) {
|
|
const mapFileName = isFunction(options.fileName)
|
|
? options.fileName
|
|
: (fileName) => fileName + (options.fileName || '.cpp');
|
|
const plugin = {
|
|
name: 'cpp',
|
|
generateBundle(outputOptions, bundle, isWrite) {
|
|
if (!isWrite)
|
|
return;
|
|
return Promise.all(Object.keys(bundle)
|
|
.map(fileName => {
|
|
const fileEntry = bundle[fileName];
|
|
// file name filter option check
|
|
const fileNameFilter = options.filter || /\.(js|mjs|json|css|html)$/;
|
|
if (isRegExp(fileNameFilter) &&
|
|
!fileName.match(fileNameFilter)) {
|
|
return Promise.resolve();
|
|
}
|
|
if (isFunction(fileNameFilter) &&
|
|
!fileNameFilter(fileName)) {
|
|
return Promise.resolve();
|
|
}
|
|
const fileContent = getOutputFileContent(fileName, fileEntry, outputOptions);
|
|
// minSize option check
|
|
if (options.minSize &&
|
|
options.minSize > fileContent.length) {
|
|
return Promise.resolve();
|
|
}
|
|
return Promise.resolve(cppCompressed(fileContent, fileName))
|
|
.then(compressedContent => {
|
|
writeFilePromise(mapFileName(fileName), compressedContent);
|
|
|
|
return null;
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
return Promise.reject('[rollup-plugin-cpp] Error compressing file ' +
|
|
fileName);
|
|
});
|
|
})
|
|
.concat([
|
|
(() => {
|
|
if (!options.additionalFiles ||
|
|
!options.additionalFiles.length)
|
|
return Promise.resolve();
|
|
const compressAdditionalFiles = () => Promise.all(options.additionalFiles.map(filePath => readFilePromise(filePath)
|
|
.then(fileContent => cppCompressed(fileContent, basename(filePath)))
|
|
.then(compressedContent => {
|
|
return writeFilePromise(mapFileName(filePath), compressedContent);
|
|
})
|
|
.catch((err) => {
|
|
return Promise.reject('[rollup-plugin-cpp] Error compressing additional file ' +
|
|
filePath + '\n' + err);
|
|
})));
|
|
// additional files can be processed outside of rollup after a delay
|
|
// for older plugins or plugins that write to disk (curcumventing rollup) without awaiting
|
|
const additionalFilesDelay = options.additionalFilesDelay ||
|
|
(VERSION >= '2.0.0' ? 0 : 2000);
|
|
if (additionalFilesDelay) {
|
|
setTimeout(compressAdditionalFiles, additionalFilesDelay);
|
|
return Promise.resolve();
|
|
}
|
|
else {
|
|
return compressAdditionalFiles();
|
|
}
|
|
})(),
|
|
]));
|
|
},
|
|
};
|
|
return plugin;
|
|
}
|
|
|
|
export default {
|
|
input: 'src/main.js',
|
|
output: {
|
|
format: 'iife',
|
|
file: './dist/index.js',
|
|
name: 'app'
|
|
},
|
|
plugins: [
|
|
svelte({}),
|
|
resolve(),
|
|
image(),
|
|
postcss({ extract: 'bundle.css' }),
|
|
htmlTemplate({
|
|
template: 'src/template.html',
|
|
target: 'index.html',
|
|
}),
|
|
terser(),
|
|
cpp({
|
|
additionalFiles: ['dist/index.html'],
|
|
fileName: function(a) { return "../src/ui_" + basename(a).replace(".", "_") + ".h"; }
|
|
})
|
|
]
|
|
};
|