@mryhryki/markdown-preview 0.5.4 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mryhryki/markdown-preview",
3
3
  "description": "Markdown realtime preview on browser",
4
- "version": "0.5.4",
4
+ "version": "0.5.6",
5
5
  "author": "mryhryki",
6
6
  "license": "MIT",
7
7
  "publishConfig": {
package/src/index.js ADDED
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const express_1 = __importDefault(require("express"));
7
+ const express_ws_1 = __importDefault(require("express-ws"));
8
+ const serve_index_1 = __importDefault(require("serve-index"));
9
+ const opener_1 = __importDefault(require("opener"));
10
+ const logger_1 = require("./lib/logger");
11
+ const show_1 = require("./lib/show");
12
+ const markdown_1 = require("./markdown");
13
+ const websocket_1 = require("./websocket");
14
+ const directory_1 = require("./lib/directory");
15
+ const params_1 = require("./lib/params");
16
+ try {
17
+ const params = new params_1.Params(process.env, process.argv.slice(2));
18
+ if (params.help)
19
+ (0, show_1.showUsage)();
20
+ if (params.version)
21
+ (0, show_1.showVersion)();
22
+ const logger = (0, logger_1.getLogger)(params.logLevel);
23
+ const previewUrl = `http://localhost:${params.port}`;
24
+ console.log("Root Directory :", directory_1.rootDir);
25
+ console.log("Default File :", params.filepath);
26
+ console.log("Extensions :", params.extensions.join(", "));
27
+ console.log("Template File :", params.template);
28
+ console.log(`Preview URL : ${previewUrl}`);
29
+ const app = (0, express_1.default)();
30
+ (0, express_ws_1.default)(app);
31
+ app.get("/", (_req, res) => res.redirect(params.filepath));
32
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
33
+ // @ts-ignore
34
+ app.ws("/ws", (0, websocket_1.WebSocketHandler)(logger));
35
+ params.extensions.forEach((ext) => {
36
+ app.get(new RegExp(`^/.+\.${ext}$`), (0, markdown_1.MarkdownHandler)(params.template));
37
+ });
38
+ app.use(express_1.default.static(directory_1.rootDir, { index: false }));
39
+ app.use(express_1.default.static(directory_1.staticDir, { index: false }));
40
+ app.use((0, serve_index_1.default)(directory_1.rootDir, { icons: true, view: "details" }));
41
+ app.listen(params.port);
42
+ if (!params.noOpener) {
43
+ (0, opener_1.default)(previewUrl);
44
+ }
45
+ }
46
+ catch (err) {
47
+ console.error(err);
48
+ (0, show_1.showUsage)(true);
49
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.templateDir = exports.staticDir = exports.projectDir = exports.rootDir = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ exports.rootDir = process.cwd();
9
+ exports.projectDir = path_1.default.resolve(__dirname, "..", "..");
10
+ exports.staticDir = path_1.default.resolve(exports.projectDir, "static");
11
+ exports.templateDir = path_1.default.resolve(exports.projectDir, "template");
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.existsFile = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ function existsFile(filepath) {
9
+ try {
10
+ fs_1.default.statSync(filepath);
11
+ return true;
12
+ }
13
+ catch (_) {
14
+ return false;
15
+ }
16
+ }
17
+ exports.existsFile = existsFile;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FileWatcher = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const directory_1 = require("./directory");
10
+ class FileWatcher {
11
+ constructor(logger) {
12
+ this.logger = logger;
13
+ this._target = {};
14
+ setInterval(() => {
15
+ Object.keys(this._target).forEach((filepath) => {
16
+ try {
17
+ const fileinfo = this._target[filepath];
18
+ const currentLastModified = this.getFileLastModified(filepath);
19
+ if (fileinfo.lastModified !== currentLastModified) {
20
+ this.logger.info("File update:", path_1.default.resolve(directory_1.rootDir, filepath));
21
+ fileinfo.lastModified = currentLastModified;
22
+ if (this._onFileChanged != null) {
23
+ this._onFileChanged(this.getFileInfo(filepath));
24
+ }
25
+ }
26
+ }
27
+ catch (err) {
28
+ console.error(err);
29
+ }
30
+ });
31
+ }, 250 /* check 4 times per second */);
32
+ }
33
+ onFileChanged(callback) {
34
+ this._onFileChanged = callback;
35
+ }
36
+ addTargetFile(filepath) {
37
+ if (this._target[filepath] != null)
38
+ return;
39
+ this.logger.debug("Add watch target:", filepath);
40
+ this._target[filepath] = {
41
+ lastModified: this.getFileLastModified(filepath),
42
+ };
43
+ }
44
+ removeTargetFile(filepath) {
45
+ if (this._target[filepath] == null)
46
+ return;
47
+ this.logger.debug("Remove watch target:", filepath);
48
+ delete this._target[filepath];
49
+ }
50
+ getFileLastModified(filepath) {
51
+ return fs_1.default.statSync(path_1.default.resolve(directory_1.rootDir, filepath)).mtimeMs;
52
+ }
53
+ getFileInfo(filepath) {
54
+ const absolutePath = path_1.default.resolve(directory_1.rootDir, filepath);
55
+ const markdown = fs_1.default.readFileSync(absolutePath, "utf-8");
56
+ return { filepath, markdown };
57
+ }
58
+ }
59
+ exports.FileWatcher = FileWatcher;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getLogger = exports.getLogLevel = void 0;
7
+ const log4js_1 = __importDefault(require("log4js"));
8
+ const LogLevels = ["trace", "debug", "info", "warn", "error", "fatal"];
9
+ function getLogLevel(level) {
10
+ switch (level) {
11
+ case "trace":
12
+ case "debug":
13
+ case "info":
14
+ case "warn":
15
+ case "error":
16
+ case "fatal":
17
+ return level;
18
+ default:
19
+ throw new Error(`Undefined log level: ${level}`);
20
+ }
21
+ }
22
+ exports.getLogLevel = getLogLevel;
23
+ function getLogger(logLevel) {
24
+ log4js_1.default.configure({
25
+ appenders: {
26
+ console: {
27
+ type: "console",
28
+ layout: {
29
+ type: "basic",
30
+ },
31
+ },
32
+ },
33
+ categories: {
34
+ default: {
35
+ appenders: ["console"],
36
+ level: logLevel,
37
+ },
38
+ },
39
+ });
40
+ return log4js_1.default.getLogger();
41
+ }
42
+ exports.getLogger = getLogger;
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Params = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const directory_1 = require("./directory");
9
+ const file_1 = require("./file");
10
+ const logger_1 = require("./logger");
11
+ class Params {
12
+ constructor(env, argv) {
13
+ const obj = Object.assign(this.getDefaultParams(), this.parseEnv(env), this.parseArgv(argv));
14
+ this._params = {
15
+ filepath: this.checkFilepath(obj.filepath),
16
+ extensions: obj.extensions,
17
+ template: this.checkTemplate(obj.template),
18
+ port: this.checkPort(obj.port),
19
+ logLevel: (0, logger_1.getLogLevel)(obj.logLevel),
20
+ noOpener: obj.noOpener,
21
+ version: obj.version,
22
+ help: obj.help,
23
+ };
24
+ }
25
+ getDefaultParams() {
26
+ return {
27
+ filepath: "README.md",
28
+ extensions: ["md", "markdown"],
29
+ template: "default",
30
+ port: 34567,
31
+ logLevel: "info",
32
+ noOpener: false,
33
+ version: false,
34
+ help: false,
35
+ };
36
+ }
37
+ parseEnv(env) {
38
+ const params = {};
39
+ if (env.MARKDOWN_PREVIEW_FILE) {
40
+ params.filepath = env.MARKDOWN_PREVIEW_FILE;
41
+ }
42
+ if (env.MARKDOWN_PREVIEW_EXTENSIONS) {
43
+ params.extensions = this.checkExtensions(env.MARKDOWN_PREVIEW_EXTENSIONS);
44
+ }
45
+ if (env.MARKDOWN_PREVIEW_TEMPLATE) {
46
+ params.template = env.MARKDOWN_PREVIEW_TEMPLATE;
47
+ }
48
+ if (env.MARKDOWN_PREVIEW_PORT) {
49
+ params.port = parseInt(env.MARKDOWN_PREVIEW_PORT, 10);
50
+ }
51
+ if (env.MARKDOWN_PREVIEW_NO_OPENER) {
52
+ params.noOpener = env.MARKDOWN_PREVIEW_NO_OPENER === "true";
53
+ }
54
+ if (env.MARKDOWN_PREVIEW_LOG_LEVEL) {
55
+ params.logLevel = (0, logger_1.getLogLevel)(env.MARKDOWN_PREVIEW_LOG_LEVEL);
56
+ }
57
+ return params;
58
+ }
59
+ parseArgv(argv) {
60
+ const params = {};
61
+ for (let i = 0; i < argv.length; i++) {
62
+ switch (argv[i]) {
63
+ case "-f":
64
+ case "--file":
65
+ params.filepath = argv[i + 1];
66
+ i++;
67
+ break;
68
+ case "-e":
69
+ case "--extensions":
70
+ params.extensions = this.checkExtensions(argv[i + 1]);
71
+ i++;
72
+ break;
73
+ case "-t":
74
+ case "--template":
75
+ params.template = argv[i + 1];
76
+ i++;
77
+ break;
78
+ case "-p":
79
+ case "--port":
80
+ params.port = parseInt(argv[i + 1], 10);
81
+ i++;
82
+ break;
83
+ case "-l":
84
+ case "--log-level":
85
+ params.logLevel = (0, logger_1.getLogLevel)(argv[i + 1]);
86
+ i++;
87
+ break;
88
+ case "--no-opener":
89
+ params.noOpener = true;
90
+ break;
91
+ case "-v":
92
+ case "--version":
93
+ params.version = true;
94
+ break;
95
+ case "-h":
96
+ case "--help":
97
+ params.help = true;
98
+ break;
99
+ default:
100
+ throw new Error(`Unknown option: ${argv[i]}`);
101
+ }
102
+ }
103
+ return params;
104
+ }
105
+ checkFilepath(filepath) {
106
+ if (path_1.default.isAbsolute(filepath)) {
107
+ throw new Error(`Absolute path is prohibited: ${filepath}`);
108
+ }
109
+ if (!(0, file_1.existsFile)(filepath)) {
110
+ throw new Error(`File not found: ${filepath}`);
111
+ }
112
+ if (path_1.default.relative(directory_1.rootDir, filepath).match(/\.\./) != null) {
113
+ throw new Error(`Illegal file path: ${filepath}`);
114
+ }
115
+ return filepath;
116
+ }
117
+ checkExtensions(extensions) {
118
+ const extensionList = extensions.split(",").map((ext) => ext.trim());
119
+ if (extensionList.length === 0) {
120
+ throw new Error(`Extensions is empty: ${extensions}`);
121
+ }
122
+ return extensionList;
123
+ }
124
+ checkTemplate(template) {
125
+ if ((0, file_1.existsFile)(path_1.default.resolve(directory_1.templateDir, `${template}.html`))) {
126
+ return path_1.default.resolve(directory_1.templateDir, `${template}.html`);
127
+ }
128
+ else if ((0, file_1.existsFile)(path_1.default.resolve(directory_1.rootDir, template))) {
129
+ return path_1.default.resolve(directory_1.rootDir, template);
130
+ }
131
+ throw new Error(`Template file not found: ${template}`);
132
+ }
133
+ checkPort(port) {
134
+ if (!isNaN(port) && 0 < port && port <= 65535) {
135
+ return port;
136
+ }
137
+ throw new Error(`Invalid port: ${port}`);
138
+ }
139
+ get filepath() {
140
+ return this._params.filepath;
141
+ }
142
+ get extensions() {
143
+ return this._params.extensions;
144
+ }
145
+ get template() {
146
+ return this._params.template;
147
+ }
148
+ get port() {
149
+ return this._params.port;
150
+ }
151
+ get logLevel() {
152
+ return this._params.logLevel;
153
+ }
154
+ get noOpener() {
155
+ return this._params.noOpener;
156
+ }
157
+ get version() {
158
+ return this._params.version;
159
+ }
160
+ get help() {
161
+ return this._params.help;
162
+ }
163
+ }
164
+ exports.Params = Params;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = __importDefault(require("path"));
7
+ const directory_1 = require("./directory");
8
+ const params_1 = require("./params");
9
+ const DEFAULT_VALUES = {
10
+ filepath: "README.md",
11
+ extensions: ["md", "markdown"],
12
+ template: path_1.default.resolve(directory_1.projectDir, "template/default.html"),
13
+ port: 34567,
14
+ logLevel: "info",
15
+ noOpener: false,
16
+ version: false,
17
+ help: false,
18
+ };
19
+ describe("Params", () => {
20
+ it("not specify", () => {
21
+ const params = new params_1.Params({}, []);
22
+ expect(params._params).toEqual(DEFAULT_VALUES);
23
+ });
24
+ it("specify all short argument", () => {
25
+ const argv = [
26
+ "-f",
27
+ "test/markdown/markdown1.md",
28
+ "-e",
29
+ "ext1,ext2",
30
+ "-t",
31
+ "test/template/template1.html",
32
+ "-p",
33
+ "100",
34
+ "-v",
35
+ "-h",
36
+ ];
37
+ const expectParams = {
38
+ filepath: "test/markdown/markdown1.md",
39
+ extensions: ["ext1", "ext2"],
40
+ template: path_1.default.resolve(directory_1.projectDir, "test/template/template1.html"),
41
+ port: 100,
42
+ logLevel: "info",
43
+ noOpener: false,
44
+ version: true,
45
+ help: true,
46
+ };
47
+ const params = new params_1.Params({}, argv);
48
+ expect(params._params).toEqual(expectParams);
49
+ });
50
+ it("specify all long argument", () => {
51
+ const argv = [
52
+ "--file",
53
+ "test/markdown/markdown1.md",
54
+ "--extensions",
55
+ "ext1,ext2",
56
+ "--template",
57
+ "test/template/template1.html",
58
+ "--port",
59
+ "100",
60
+ "--log-level",
61
+ "trace",
62
+ "--no-opener",
63
+ "--version",
64
+ "--help",
65
+ ];
66
+ const expectParams = {
67
+ filepath: "test/markdown/markdown1.md",
68
+ extensions: ["ext1", "ext2"],
69
+ template: path_1.default.resolve(directory_1.projectDir, "test/template/template1.html"),
70
+ port: 100,
71
+ logLevel: "trace",
72
+ noOpener: true,
73
+ version: true,
74
+ help: true,
75
+ };
76
+ const params = new params_1.Params({}, argv);
77
+ expect(params._params).toEqual(expectParams);
78
+ });
79
+ it("specify all environment variable", () => {
80
+ const env = {
81
+ MARKDOWN_PREVIEW_FILE: "test/markdown/markdown1.md",
82
+ MARKDOWN_PREVIEW_EXTENSIONS: "ext1, ext2",
83
+ MARKDOWN_PREVIEW_TEMPLATE: "test/template/template1.html",
84
+ MARKDOWN_PREVIEW_PORT: "100",
85
+ MARKDOWN_PREVIEW_LOG_LEVEL: "trace",
86
+ MARKDOWN_PREVIEW_NO_OPENER: "true",
87
+ };
88
+ const expectParams = {
89
+ filepath: "test/markdown/markdown1.md",
90
+ extensions: ["ext1", "ext2"],
91
+ template: path_1.default.resolve(directory_1.projectDir, "test/template/template1.html"),
92
+ port: 100,
93
+ logLevel: "trace",
94
+ noOpener: true,
95
+ version: false,
96
+ help: false,
97
+ };
98
+ const params = new params_1.Params(env, []);
99
+ expect(params._params).toEqual(expectParams);
100
+ });
101
+ });
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.showVersion = exports.showUsage = void 0;
27
+ const pkg = __importStar(require("../../package.json"));
28
+ function showUsage(error = false) {
29
+ const usage = `
30
+ Usage:
31
+ npx @mryhryki/markdown-preview [options]
32
+ markdown-preview [options]
33
+
34
+ Options:
35
+ -f,--file [relative_file_path] Default: README.md
36
+ -t,--template [template_name] Default: default
37
+ -p,--port [port_number] Default: 34567
38
+ -v,--version
39
+ -h,--help
40
+ `;
41
+ console.log(usage);
42
+ process.exit(error ? 1 : 0);
43
+ }
44
+ exports.showUsage = showUsage;
45
+ function showVersion() {
46
+ console.log(pkg.version);
47
+ process.exit(0);
48
+ }
49
+ exports.showVersion = showVersion;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SocketManager = void 0;
4
+ class SocketManager {
5
+ constructor() {
6
+ this._sockets = [];
7
+ }
8
+ addSocket(socket, filepath) {
9
+ this._sockets.push({ socket, filepath });
10
+ }
11
+ removeSocket(socket) {
12
+ this._sockets = this._sockets.filter(({ socket: s }) => s !== socket);
13
+ }
14
+ getSockets(filepath) {
15
+ return this._sockets.filter(({ filepath: fp }) => fp === filepath).map((s) => s.socket);
16
+ }
17
+ countSocket(filepath = null) {
18
+ if (filepath == null) {
19
+ return this._sockets.length;
20
+ }
21
+ return this.getSockets(filepath).length;
22
+ }
23
+ }
24
+ exports.SocketManager = SocketManager;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const socket_manager_1 = require("./socket_manager");
4
+ const dummySocket1 = { name: "socket1" }; // eslint-disable-line @typescript-eslint/no-explicit-any
5
+ const dummySocket2 = { name: "socket2" }; // eslint-disable-line @typescript-eslint/no-explicit-any
6
+ const dummySocket3 = { name: "socket3" }; // eslint-disable-line @typescript-eslint/no-explicit-any
7
+ const dummyFilepath1 = "file1";
8
+ const dummyFilepath2 = "file2";
9
+ const dummyInfo1 = { socket: dummySocket1, filepath: dummyFilepath1 };
10
+ const dummyInfo2 = { socket: dummySocket2, filepath: dummyFilepath2 };
11
+ const dummyInfo3 = { socket: dummySocket3, filepath: dummyFilepath2 };
12
+ describe("SocketManager", () => {
13
+ it("works normally", () => {
14
+ const socketManager = new socket_manager_1.SocketManager();
15
+ expect(socketManager._sockets).toEqual([]);
16
+ socketManager.addSocket(dummySocket1, dummyFilepath1);
17
+ expect(socketManager._sockets).toEqual([dummyInfo1]);
18
+ socketManager.addSocket(dummySocket2, dummyFilepath2);
19
+ expect(socketManager._sockets).toEqual([dummyInfo1, dummyInfo2]);
20
+ socketManager.addSocket(dummySocket3, dummyFilepath2);
21
+ expect(socketManager._sockets).toEqual([dummyInfo1, dummyInfo2, dummyInfo3]);
22
+ expect(socketManager.getSockets(dummyFilepath1)).toEqual([dummySocket1]);
23
+ expect(socketManager.getSockets(dummyFilepath2)).toEqual([dummySocket2, dummySocket3]);
24
+ expect(socketManager.countSocket()).toEqual(3);
25
+ expect(socketManager.countSocket(dummyFilepath1)).toEqual(1);
26
+ expect(socketManager.countSocket(dummyFilepath2)).toEqual(2);
27
+ socketManager.removeSocket(dummySocket2);
28
+ expect(socketManager._sockets).toEqual([dummyInfo1, dummyInfo3]);
29
+ socketManager.removeSocket(dummySocket1);
30
+ expect(socketManager._sockets).toEqual([dummyInfo3]);
31
+ socketManager.removeSocket(dummySocket3);
32
+ expect(socketManager._sockets).toEqual([]);
33
+ });
34
+ });
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MarkdownHandler = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const directory_1 = require("./lib/directory");
9
+ const file_1 = require("./lib/file");
10
+ function MarkdownHandler(template) {
11
+ return (req, res, next) => {
12
+ const filepath = path_1.default.resolve(directory_1.rootDir, decodeURIComponent(req.path.substr(1)));
13
+ if ((0, file_1.existsFile)(filepath)) {
14
+ res.sendFile(template);
15
+ }
16
+ else {
17
+ next();
18
+ }
19
+ };
20
+ }
21
+ exports.MarkdownHandler = MarkdownHandler;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WebSocketHandler = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const file_watcher_1 = require("./lib/file_watcher");
9
+ const socket_manager_1 = require("./lib/socket_manager");
10
+ const directory_1 = require("./lib/directory");
11
+ function WebSocketHandler(logger) {
12
+ let socketSeqNo = 1;
13
+ const socketManager = new socket_manager_1.SocketManager();
14
+ const fileWatcher = new file_watcher_1.FileWatcher(logger);
15
+ fileWatcher.onFileChanged((fileinfo) => {
16
+ socketManager.getSockets(fileinfo.filepath).forEach((ws) => {
17
+ ws.send(JSON.stringify(fileinfo));
18
+ });
19
+ });
20
+ return (ws, req) => {
21
+ const wsSeqNo = socketSeqNo++;
22
+ try {
23
+ logger.debug("WebSocket connected:", wsSeqNo);
24
+ const pathInQuery = typeof req.query.path === "string" ? req.query.path : "";
25
+ const filepath = path_1.default.resolve(directory_1.rootDir, decodeURIComponent(pathInQuery.substring(1)));
26
+ fileWatcher.addTargetFile(filepath);
27
+ socketManager.addSocket(ws, filepath);
28
+ ws.on("close", () => {
29
+ logger.debug("WebSocket close:", wsSeqNo);
30
+ socketManager.removeSocket(ws);
31
+ if (socketManager.countSocket(filepath) === 0) {
32
+ fileWatcher.removeTargetFile(filepath);
33
+ }
34
+ });
35
+ ws.send(JSON.stringify(fileWatcher.getFileInfo(filepath)));
36
+ }
37
+ catch (e) {
38
+ logger.error(e);
39
+ }
40
+ };
41
+ }
42
+ exports.WebSocketHandler = WebSocketHandler;