194 lines
6.8 KiB
JavaScript
194 lines
6.8 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const tiny_lr_1 = __importDefault(require("tiny-lr"));
|
|
const open_1 = __importDefault(require("open"));
|
|
const immutable_1 = __importDefault(require("immutable"));
|
|
const parse_1 = __importDefault(require("../parse"));
|
|
const output_1 = __importDefault(require("../output"));
|
|
const modifiers_1 = __importDefault(require("../modifiers"));
|
|
const promise_1 = __importDefault(require("../utils/promise"));
|
|
const options_1 = __importDefault(require("./options"));
|
|
const getBook_1 = __importDefault(require("./getBook"));
|
|
const getOutputFolder_1 = __importDefault(require("./getOutputFolder"));
|
|
const server_1 = __importDefault(require("./server"));
|
|
const watch_1 = __importDefault(require("./watch"));
|
|
const page_cache_1 = require("../output/page-cache");
|
|
const fs_1 = __importDefault(require("fs"));
|
|
let server, lrServer, lrPath;
|
|
function waitForCtrlC() {
|
|
const d = promise_1.default.defer();
|
|
process.on("SIGINT", () => {
|
|
d.resolve();
|
|
});
|
|
return d.promise;
|
|
}
|
|
function startServer(args, kwargs) {
|
|
const outputFolder = (0, getOutputFolder_1.default)(args);
|
|
const port = kwargs.port;
|
|
const browser = kwargs["browser"];
|
|
const book = (0, getBook_1.default)(args, kwargs);
|
|
const hasWatch = kwargs["watch"];
|
|
const hasOpen = kwargs["open"];
|
|
const hasLiveReloading = kwargs["live"];
|
|
const reload = kwargs["reload"];
|
|
const Generator = output_1.default.getGenerator(kwargs.format);
|
|
const logger = book.getLogger();
|
|
logger.info.ok("Starting server ...");
|
|
let lastOutput = null;
|
|
return promise_1.default.all([
|
|
server.start(outputFolder, port),
|
|
generateBook({
|
|
book,
|
|
outputFolder,
|
|
hasLiveReloading,
|
|
Generator,
|
|
reload
|
|
}).then((output) => {
|
|
lastOutput = output;
|
|
return output;
|
|
})
|
|
])
|
|
.then(() => {
|
|
console.log(`Serving book on http://localhost:${port}`);
|
|
if (hasOpen) {
|
|
(0, open_1.default)(`http://localhost:${port}`, { app: browser });
|
|
}
|
|
})
|
|
.then(() => {
|
|
if (!hasWatch) {
|
|
return waitForCtrlC();
|
|
}
|
|
// update book immutably. does not use book again
|
|
return (0, watch_1.default)(book.getRoot(), (error, filepath) => {
|
|
if (error) {
|
|
console.error(error);
|
|
return;
|
|
}
|
|
// If the file does not exist in file system, show a warning and skip
|
|
// Probably, the file has been deleted
|
|
if (!fs_1.default.existsSync(filepath)) {
|
|
logger.warn.ok(`${filepath} does not exist in file system.`);
|
|
return;
|
|
}
|
|
// set livereload path
|
|
lrPath = filepath;
|
|
// TODO: use parse extension
|
|
// Incremental update for pages
|
|
if (lastOutput && filepath.endsWith(".md")) {
|
|
logger.warn.ok("Rebuild " + filepath);
|
|
const changedOutput = lastOutput.reloadPage(lastOutput.book.getContentRoot(), filepath).merge({
|
|
incrementalChangeFileSet: immutable_1.default.Set([filepath])
|
|
});
|
|
return incrementalBuild({
|
|
output: changedOutput,
|
|
Generator
|
|
}).then(() => {
|
|
if (lrPath && hasLiveReloading) {
|
|
// trigger livereload
|
|
lrServer.changed({
|
|
body: {
|
|
files: [lrPath]
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
// Asciidoc files are not supported for incremental build
|
|
logger.info.ok("Rebuild " + filepath);
|
|
return generateBook({
|
|
book,
|
|
outputFolder,
|
|
hasLiveReloading,
|
|
Generator,
|
|
reload
|
|
}).then((output) => {
|
|
lastOutput = output;
|
|
});
|
|
});
|
|
});
|
|
}
|
|
function generateBook({ book, outputFolder, hasLiveReloading, Generator, reload }) {
|
|
// Stop server if running
|
|
if (reload) {
|
|
book.getLogger().info.ok(`Clear cache`);
|
|
(0, page_cache_1.clearCache)();
|
|
}
|
|
return parse_1.default.parseBook(book).then((resultBook) => {
|
|
if (hasLiveReloading) {
|
|
// Enable livereload plugin
|
|
let config = resultBook.getConfig();
|
|
// @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2.
|
|
config = modifiers_1.default.Config.addPlugin(config, "livereload");
|
|
resultBook = resultBook.set("config", config);
|
|
}
|
|
return output_1.default.generate(Generator, resultBook, {
|
|
root: outputFolder
|
|
});
|
|
});
|
|
}
|
|
function incrementalBuild({ output, Generator }) {
|
|
return output_1.default.incrementalBuild(Generator, output);
|
|
}
|
|
exports.default = {
|
|
name: "serve [book] [output]",
|
|
description: "serve the book as a website for testing",
|
|
options: [
|
|
{
|
|
name: "port",
|
|
description: "Port for server to listen on",
|
|
defaults: 4000
|
|
},
|
|
{
|
|
name: "lrport",
|
|
description: "Port for livereload server to listen on",
|
|
defaults: 35729
|
|
},
|
|
{
|
|
name: "watch",
|
|
description: "Enable file watcher and live reloading",
|
|
defaults: true
|
|
},
|
|
{
|
|
name: "live",
|
|
description: "Enable live reloading",
|
|
defaults: true
|
|
},
|
|
{
|
|
name: "open",
|
|
description: "Enable opening book in browser",
|
|
defaults: false
|
|
},
|
|
{
|
|
name: "browser",
|
|
description: "Specify browser for opening book",
|
|
defaults: ""
|
|
},
|
|
options_1.default.log,
|
|
options_1.default.format,
|
|
options_1.default.reload
|
|
],
|
|
exec: function (args, kwargs) {
|
|
server = new server_1.default();
|
|
const hasWatch = kwargs["watch"];
|
|
const hasLiveReloading = kwargs["live"];
|
|
return (0, promise_1.default)()
|
|
.then(() => {
|
|
if (!hasWatch || !hasLiveReloading) {
|
|
return;
|
|
}
|
|
lrServer = (0, tiny_lr_1.default)({});
|
|
return promise_1.default.nfcall(lrServer.listen.bind(lrServer), kwargs.lrport).then(() => {
|
|
console.log("Live reload server started on port:", kwargs.lrport);
|
|
console.log("Press CTRL+C to quit ...");
|
|
console.log("");
|
|
});
|
|
})
|
|
.then(() => {
|
|
return startServer(args, kwargs);
|
|
});
|
|
}
|
|
};
|