@lexho111/plainblog 0.7.2 → 0.7.4
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/Article.js +82 -90
- package/Article.ts +97 -0
- package/AssetManager.js +63 -116
- package/Auth.js +2 -2
- package/Blog.js +103 -82
- package/cluster-server.js +36 -31
- package/debug-loader.js +16 -1
- package/index.js +2 -0
- package/model/DataModel.js +11 -9
- package/model/SqliteAdapter.js +15 -7
- package/model/datastructures/BinarySearchTree.js +1 -1
- package/modules/csscompiler/compile-style-worker.js +72 -0
- package/modules/csscompiler/csscompiler.js +135 -0
- package/modules/jscompiler/compile-js-worker.js +34 -0
- package/{build-scripts.js → modules/jscompiler/jscompiler.js} +3 -1
- package/package.json +4 -7
- package/public/styles.min.css +8 -2
- package/router.js +60 -64
- package/server.js +190 -155
- package/src/styles.css +1 -1
- package/styles.hash +1 -0
- package/tsconfig.json +12 -0
- package/.dependency-cruiser.cjs +0 -382
- package/ArrayList.cpuprofile +0 -1
- package/BinarySearchTree.cpuprofile +0 -1
- package/FlameChartProfile.cpuprofile +0 -1
- package/FlameChartProfile2.cpuprofile +0 -1
- package/FlameChartProfile3.cpuprofile +0 -1
- package/StandaloneProfile.cpuprofile +0 -1
- package/blog_test_empty +0 -0
- package/blog_test_load +0 -0
- package/build-styles.js +0 -87
- package/workers/compiler-worker.js +0 -42
package/Article.js
CHANGED
|
@@ -1,96 +1,88 @@
|
|
|
1
|
-
export default class Article {
|
|
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
|
-
toHTML(loggedin = false) {
|
|
81
|
-
if (this.content == null) return "";
|
|
82
|
-
const moreButton = this.content.length > 400 ? `<a href="#">more</a>` : "";
|
|
83
|
-
const buttons = loggedin // prettier-ignore
|
|
84
|
-
? `<div class="buttons"><div id="editButton${this.id}" class="btn edit" role="button" tabindex="0" data-action="edit" data-id="${this.id}">edit</div><div id="deleteButton${this.id}" class="btn delete" role="button" tabindex="0" data-action="delete" data-id="${this.id}">delete</div><div id="somethingelseButton${this.id}" class="btn light">something else</div></div>`
|
|
85
|
-
: "";
|
|
86
|
-
// prettier-ignore
|
|
87
|
-
return `<article data-id="${this.id}" data-date="${this.createdAt}">
|
|
1
|
+
export default class Article {
|
|
2
|
+
constructor(id, title, content, createdAt) {
|
|
3
|
+
this.id = id;
|
|
4
|
+
this.title = title;
|
|
5
|
+
this.content = content;
|
|
6
|
+
this.createdAt = new Date(createdAt).getTime();
|
|
7
|
+
}
|
|
8
|
+
static createNew(title, content, createdAt = new Date()) {
|
|
9
|
+
const id = this.getNextID(); // Your existing ID generator
|
|
10
|
+
//const createdAt = new Date();
|
|
11
|
+
return new Article(id, title, content, createdAt);
|
|
12
|
+
}
|
|
13
|
+
static getNextID() {
|
|
14
|
+
// Generiert eine kollisionssichere ID basierend auf Zeitstempel + Zufall
|
|
15
|
+
// Passt in JS Safe Integer und SQLite Integer (64-bit)
|
|
16
|
+
return Date.now() * 1000 + Math.floor(Math.random() * 1000);
|
|
17
|
+
}
|
|
18
|
+
getContent() {
|
|
19
|
+
return this.content;
|
|
20
|
+
}
|
|
21
|
+
getContentVeryShort() {
|
|
22
|
+
if (!this.content)
|
|
23
|
+
return "";
|
|
24
|
+
if (this.content.length < 50)
|
|
25
|
+
return this.content;
|
|
26
|
+
let contentShort = this.content.substring(0, 50);
|
|
27
|
+
contentShort += "...";
|
|
28
|
+
return contentShort;
|
|
29
|
+
}
|
|
30
|
+
getContentShort() {
|
|
31
|
+
if (!this.content)
|
|
32
|
+
return "";
|
|
33
|
+
if (this.content.length < 400)
|
|
34
|
+
return this.content;
|
|
35
|
+
let contentShort = this.content.substring(0, 400);
|
|
36
|
+
contentShort += "...";
|
|
37
|
+
return contentShort;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns a JSON-serializable representation of the article.
|
|
41
|
+
* This method is automatically called by JSON.stringify().
|
|
42
|
+
*/
|
|
43
|
+
toJSON() {
|
|
44
|
+
// Return a plain object with the desired properties
|
|
45
|
+
const date = !isNaN(this.createdAt)
|
|
46
|
+
? new Date(this.createdAt).toISOString()
|
|
47
|
+
: new Date().toISOString();
|
|
48
|
+
return {
|
|
49
|
+
id: this.id,
|
|
50
|
+
title: this.title,
|
|
51
|
+
content: this.content,
|
|
52
|
+
createdAt: date,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Returns a JSON-serializable representation of the article.
|
|
57
|
+
* This method is automatically called by JSON.stringify().
|
|
58
|
+
*/
|
|
59
|
+
json() {
|
|
60
|
+
return this.toJSON();
|
|
61
|
+
}
|
|
62
|
+
getFormattedDate() {
|
|
63
|
+
const date = new Date(this.createdAt);
|
|
64
|
+
const year = date.getFullYear();
|
|
65
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
66
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
67
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
68
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
69
|
+
return `${year}/${month}/${day} ${hours}:${minutes}`;
|
|
70
|
+
}
|
|
71
|
+
toHTML(loggedin = false) {
|
|
72
|
+
if (this.content == null)
|
|
73
|
+
return "";
|
|
74
|
+
const moreButton = this.content.length > 400 ? `<a href="#">more</a>` : "";
|
|
75
|
+
const buttons = loggedin // prettier-ignore
|
|
76
|
+
? `<div class="buttons"><div id="editButton${this.id}" class="btn edit" role="button" tabindex="0" data-action="edit" data-id="${this.id}">edit</div><div id="deleteButton${this.id}" class="btn delete" role="button" tabindex="0" data-action="delete" data-id="${this.id}">delete</div><div id="somethingelseButton${this.id}" class="btn light">something else</div></div>`
|
|
77
|
+
: "";
|
|
78
|
+
// prettier-ignore
|
|
79
|
+
return `<article data-id="${this.id}" data-date="${this.createdAt}">
|
|
88
80
|
${buttons}
|
|
89
81
|
<h2>${this.title}</h2>
|
|
90
82
|
<span class="datetime">${this.getFormattedDate()}</span>
|
|
91
83
|
<p>${this.getContentShort()}</p>
|
|
92
84
|
<div class="full-content" style="display: none;">${this.content}</div>
|
|
93
85
|
${moreButton}
|
|
94
|
-
</article>`;
|
|
95
|
-
|
|
96
|
-
}
|
|
86
|
+
</article>`;
|
|
87
|
+
}
|
|
88
|
+
}
|
package/Article.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export default class Article {
|
|
2
|
+
id: number;
|
|
3
|
+
title: string;
|
|
4
|
+
content: string;
|
|
5
|
+
createdAt: number;
|
|
6
|
+
|
|
7
|
+
constructor(id: number, title: string, content: string, createdAt: string | number | Date) {
|
|
8
|
+
this.id = id;
|
|
9
|
+
this.title = title;
|
|
10
|
+
this.content = content;
|
|
11
|
+
this.createdAt = new Date(createdAt).getTime();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static createNew(title: string, content: string, createdAt: string | number | Date = new Date()): Article {
|
|
15
|
+
const id = this.getNextID(); // Your existing ID generator
|
|
16
|
+
//const createdAt = new Date();
|
|
17
|
+
return new Article(id, title, content, createdAt);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static getNextID(): number {
|
|
21
|
+
// Generiert eine kollisionssichere ID basierend auf Zeitstempel + Zufall
|
|
22
|
+
// Passt in JS Safe Integer und SQLite Integer (64-bit)
|
|
23
|
+
return Date.now() * 1000 + Math.floor(Math.random() * 1000);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getContent(): string {
|
|
27
|
+
return this.content;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
getContentVeryShort(): string {
|
|
31
|
+
if (!this.content) return "";
|
|
32
|
+
if (this.content.length < 50) return this.content;
|
|
33
|
+
let contentShort = this.content.substring(0, 50);
|
|
34
|
+
contentShort += "...";
|
|
35
|
+
return contentShort;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getContentShort(): string {
|
|
39
|
+
if (!this.content) return "";
|
|
40
|
+
if (this.content.length < 400) return this.content;
|
|
41
|
+
let contentShort = this.content.substring(0, 400);
|
|
42
|
+
contentShort += "...";
|
|
43
|
+
return contentShort;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Returns a JSON-serializable representation of the article.
|
|
48
|
+
* This method is automatically called by JSON.stringify().
|
|
49
|
+
*/
|
|
50
|
+
toJSON(): { id: number; title: string; content: string; createdAt: string } {
|
|
51
|
+
// Return a plain object with the desired properties
|
|
52
|
+
const date = !isNaN(this.createdAt)
|
|
53
|
+
? new Date(this.createdAt).toISOString()
|
|
54
|
+
: new Date().toISOString();
|
|
55
|
+
return {
|
|
56
|
+
id: this.id,
|
|
57
|
+
title: this.title,
|
|
58
|
+
content: this.content,
|
|
59
|
+
createdAt: date,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Returns a JSON-serializable representation of the article.
|
|
65
|
+
* This method is automatically called by JSON.stringify().
|
|
66
|
+
*/
|
|
67
|
+
json(): { id: number; title: string; content: string; createdAt: string } {
|
|
68
|
+
return this.toJSON();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getFormattedDate(): string {
|
|
72
|
+
const date = new Date(this.createdAt);
|
|
73
|
+
const year = date.getFullYear();
|
|
74
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
75
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
76
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
77
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
78
|
+
return `${year}/${month}/${day} ${hours}:${minutes}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
toHTML(loggedin = false): string {
|
|
82
|
+
if (this.content == null) return "";
|
|
83
|
+
const moreButton = this.content.length > 400 ? `<a href="#">more</a>` : "";
|
|
84
|
+
const buttons = loggedin // prettier-ignore
|
|
85
|
+
? `<div class="buttons"><div id="editButton${this.id}" class="btn edit" role="button" tabindex="0" data-action="edit" data-id="${this.id}">edit</div><div id="deleteButton${this.id}" class="btn delete" role="button" tabindex="0" data-action="delete" data-id="${this.id}">delete</div><div id="somethingelseButton${this.id}" class="btn light">something else</div></div>`
|
|
86
|
+
: "";
|
|
87
|
+
// prettier-ignore
|
|
88
|
+
return `<article data-id="${this.id}" data-date="${this.createdAt}">
|
|
89
|
+
${buttons}
|
|
90
|
+
<h2>${this.title}</h2>
|
|
91
|
+
<span class="datetime">${this.getFormattedDate()}</span>
|
|
92
|
+
<p>${this.getContentShort()}</p>
|
|
93
|
+
<div class="full-content" style="display: none;">${this.content}</div>
|
|
94
|
+
${moreButton}
|
|
95
|
+
</article>`;
|
|
96
|
+
}
|
|
97
|
+
}
|
package/AssetManager.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from "path";
|
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
5
|
import { Worker } from "node:worker_threads";
|
|
6
6
|
import { createDebug } from "./debug-loader.js";
|
|
7
|
+
import { checkSourceCSS } from "./modules/csscompiler/csscompiler.js";
|
|
7
8
|
|
|
8
9
|
const debug = createDebug("plainblog:AssetManager");
|
|
9
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -13,27 +14,30 @@ export default class AssetManager {
|
|
|
13
14
|
constructor() {
|
|
14
15
|
this.publicDir = path.join(process.cwd(), "public");
|
|
15
16
|
this.reloadStylesOnGET = false;
|
|
16
|
-
this.
|
|
17
|
+
this._stylesheetPath = null;
|
|
17
18
|
this.compilestyle = false;
|
|
18
|
-
this.
|
|
19
|
-
this.compiledStyles = "";
|
|
20
|
-
this.stylesHash = "";
|
|
19
|
+
this._styles = "";
|
|
21
20
|
this.scriptsHash = "";
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
set style(value) {
|
|
24
|
+
debug("set style %s", value);
|
|
25
|
+
this._styles += value;
|
|
26
26
|
this.compilestyle = true;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
set stylesheetPath(value) {
|
|
30
|
+
debug(`set Stylesheet path: ${value}`);
|
|
31
|
+
this._stylesheetPath = value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get stylesheetPath() {
|
|
35
|
+
return this._stylesheetPath;
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
async init() {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
await this.processStylesheets(this.stylesheetPath);
|
|
33
|
-
}
|
|
34
|
-
if (!this.stylesheetPath) {
|
|
35
|
-
await this.processDefaultStyles();
|
|
36
|
-
}
|
|
39
|
+
debug("init");
|
|
40
|
+
await this.processStyles();
|
|
37
41
|
|
|
38
42
|
// Process Scripts
|
|
39
43
|
const srcScriptPath = path.join(__dirname, "src", "fetchData.js");
|
|
@@ -42,112 +46,35 @@ export default class AssetManager {
|
|
|
42
46
|
|
|
43
47
|
async reload() {
|
|
44
48
|
debug("reload");
|
|
45
|
-
|
|
46
|
-
await this.processStylesheets(this.stylesheetPath);
|
|
47
|
-
}
|
|
48
|
-
if (!this.stylesheetPath) {
|
|
49
|
-
await this.processDefaultStyles();
|
|
50
|
-
}
|
|
49
|
+
await this.processStyles();
|
|
51
50
|
const srcScriptPath = path.join(__dirname, "src", "fetchData.js");
|
|
52
51
|
await this.processScripts(srcScriptPath);
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
async
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
let srcStyles = "";
|
|
62
|
-
|
|
63
|
-
await Promise.all([
|
|
64
|
-
fs.promises
|
|
65
|
-
.readFile(publicStylePath, "utf8")
|
|
66
|
-
.then((publicCSS) => {
|
|
67
|
-
const match = publicCSS.match(
|
|
68
|
-
/\/\* source-hash: ([a-f0-9]{64}) \*\//,
|
|
69
|
-
);
|
|
70
|
-
if (match) publicHash = match[1];
|
|
71
|
-
})
|
|
72
|
-
.catch((err) => {
|
|
73
|
-
if (err.code !== "ENOENT" && !err.message.includes("ENOENT"))
|
|
74
|
-
console.error(err);
|
|
75
|
-
}),
|
|
76
|
-
fs.promises
|
|
77
|
-
.readFile(srcStylePath, "utf8")
|
|
78
|
-
.then((content) => {
|
|
79
|
-
srcStyles = content;
|
|
80
|
-
})
|
|
81
|
-
.catch((err) => {
|
|
82
|
-
if (err.code !== "ENOENT" && !err.message.includes("ENOENT"))
|
|
83
|
-
console.error(err);
|
|
84
|
-
}),
|
|
85
|
-
]);
|
|
86
|
-
|
|
87
|
-
const combinedStyles = srcStyles + "\n" + this.styles;
|
|
88
|
-
const srcHash = crypto
|
|
89
|
-
.createHash("sha256")
|
|
90
|
-
.update(combinedStyles)
|
|
91
|
-
.digest("hex");
|
|
92
|
-
|
|
93
|
-
if (srcHash !== publicHash) {
|
|
94
|
-
debug("Styles have changed. Recompiling in worker...");
|
|
95
|
-
const finalStyles = await this.runWorker("mergeStyles", [
|
|
96
|
-
srcStyles,
|
|
97
|
-
this.styles,
|
|
98
|
-
]);
|
|
99
|
-
|
|
100
|
-
try {
|
|
101
|
-
await fs.promises.mkdir(path.dirname(publicStylePath), {
|
|
102
|
-
recursive: true,
|
|
103
|
-
});
|
|
104
|
-
await fs.promises.writeFile(
|
|
105
|
-
publicStylePath,
|
|
106
|
-
finalStyles + `\n/* source-hash: ${srcHash} */`,
|
|
54
|
+
async processStyles(compilerOptions = {}) {
|
|
55
|
+
let resolvedStylesheetPath = this.stylesheetPath;
|
|
56
|
+
if (resolvedStylesheetPath) {
|
|
57
|
+
if (Array.isArray(resolvedStylesheetPath)) {
|
|
58
|
+
resolvedStylesheetPath = resolvedStylesheetPath.map((p) =>
|
|
59
|
+
path.isAbsolute(p) ? p : path.resolve(process.cwd(), p),
|
|
107
60
|
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
debug("process stylesheets");
|
|
116
|
-
const fileList = Array.isArray(files) ? files : [files];
|
|
117
|
-
const styleFiles = fileList.filter(
|
|
118
|
-
(f) =>
|
|
119
|
-
typeof f === "string" &&
|
|
120
|
-
(f.endsWith(".scss") || f.endsWith(".css")) &&
|
|
121
|
-
!f.endsWith(".min.css"),
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
if (styleFiles.length > 0) {
|
|
125
|
-
const fileData = await Promise.all(
|
|
126
|
-
styleFiles.sort().map(async (f) => {
|
|
127
|
-
const content = await fs.promises.readFile(f, "utf-8");
|
|
128
|
-
if (content == "") throw new Error("Invalid Filepath or empty file!");
|
|
129
|
-
return { path: f, content };
|
|
130
|
-
}),
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
const hash = crypto.createHash("sha256");
|
|
134
|
-
for (const file of fileData) hash.update(file.content);
|
|
135
|
-
const currentHash = hash.digest("hex");
|
|
136
|
-
|
|
137
|
-
if (currentHash !== this.stylesHash && this.compilestyle) {
|
|
138
|
-
console.log("style assets have changed. recompiling in worker...");
|
|
139
|
-
this.stylesHash = currentHash;
|
|
140
|
-
this.compiledStyles = await this.runWorker("styles", fileData);
|
|
141
|
-
|
|
142
|
-
await fs.promises.mkdir(this.publicDir, { recursive: true });
|
|
143
|
-
await fs.promises.writeFile(
|
|
144
|
-
path.join(this.publicDir, "styles.min.css"),
|
|
145
|
-
this.compiledStyles + `\n/* source-hash: ${currentHash} */`,
|
|
61
|
+
} else if (
|
|
62
|
+
typeof resolvedStylesheetPath === "string" &&
|
|
63
|
+
!path.isAbsolute(resolvedStylesheetPath)
|
|
64
|
+
) {
|
|
65
|
+
resolvedStylesheetPath = path.resolve(
|
|
66
|
+
process.cwd(),
|
|
67
|
+
resolvedStylesheetPath,
|
|
146
68
|
);
|
|
147
|
-
} else {
|
|
148
|
-
console.log("styles are up-to-date");
|
|
149
69
|
}
|
|
150
70
|
}
|
|
71
|
+
await checkSourceCSS({
|
|
72
|
+
stylesheetPath: resolvedStylesheetPath,
|
|
73
|
+
style: this._styles,
|
|
74
|
+
outputDir: this.publicDir,
|
|
75
|
+
outputPath: path.join(this.publicDir, "styles.min.css"),
|
|
76
|
+
...compilerOptions,
|
|
77
|
+
});
|
|
151
78
|
}
|
|
152
79
|
|
|
153
80
|
async processScripts(files) {
|
|
@@ -184,14 +111,28 @@ export default class AssetManager {
|
|
|
184
111
|
}
|
|
185
112
|
|
|
186
113
|
if (currentHash !== this.scriptsHash) {
|
|
187
|
-
console.log("script assets have changed. recompiling
|
|
188
|
-
|
|
189
|
-
|
|
114
|
+
console.log("script assets have changed. recompiling...");
|
|
115
|
+
let compiledScripts;
|
|
116
|
+
let success = false;
|
|
117
|
+
try {
|
|
118
|
+
compiledScripts = await this.runWorker("scripts", fileData);
|
|
119
|
+
success = true;
|
|
120
|
+
this.scriptsHash = currentHash;
|
|
121
|
+
} catch (e) {
|
|
122
|
+
console.warn(
|
|
123
|
+
"Script compilation failed (using fallback):",
|
|
124
|
+
e.message,
|
|
125
|
+
);
|
|
126
|
+
compiledScripts = fileData.map((f) => f.content).join(";\n");
|
|
127
|
+
}
|
|
190
128
|
|
|
191
129
|
await fs.promises.mkdir(this.publicDir, { recursive: true });
|
|
130
|
+
const content = success
|
|
131
|
+
? compiledScripts + `\n/* source-hash: ${currentHash} */`
|
|
132
|
+
: compiledScripts;
|
|
192
133
|
await fs.promises.writeFile(
|
|
193
134
|
path.join(this.publicDir, "scripts.min.js"),
|
|
194
|
-
|
|
135
|
+
content,
|
|
195
136
|
);
|
|
196
137
|
}
|
|
197
138
|
}
|
|
@@ -205,11 +146,17 @@ export default class AssetManager {
|
|
|
205
146
|
: { type, fileData: data };
|
|
206
147
|
|
|
207
148
|
const worker = new Worker(
|
|
208
|
-
path.resolve(
|
|
149
|
+
path.resolve(
|
|
150
|
+
__dirname,
|
|
151
|
+
"modules",
|
|
152
|
+
"jscompiler",
|
|
153
|
+
"compile-js-worker.js",
|
|
154
|
+
),
|
|
209
155
|
{ workerData },
|
|
210
156
|
);
|
|
211
157
|
worker.on("message", (msg) => {
|
|
212
158
|
if (msg.status === "success") {
|
|
159
|
+
console.log("compilation complete: public/styles.min.css created");
|
|
213
160
|
resolve(msg.result);
|
|
214
161
|
} else {
|
|
215
162
|
reject(new Error(msg.error));
|
package/Auth.js
CHANGED
|
@@ -16,14 +16,14 @@ export default class Auth {
|
|
|
16
16
|
if (!req.headers.cookie) {
|
|
17
17
|
const time_end = performance.now();
|
|
18
18
|
const duration = time_end - time_start;
|
|
19
|
-
debug_perf("isAuthenticated
|
|
19
|
+
debug_perf("isAuthenticated", duration);
|
|
20
20
|
return false;
|
|
21
21
|
}
|
|
22
22
|
const match = req.headers.cookie.match(/(?:^|;\s*)session=([^;]*)/);
|
|
23
23
|
const result = match ? this.sessions.has(match[1]) : false;
|
|
24
24
|
const time_end = performance.now();
|
|
25
25
|
const duration = time_end - time_start;
|
|
26
|
-
debug_perf("isAuthenticated
|
|
26
|
+
debug_perf("isAuthenticated", duration);
|
|
27
27
|
return result;
|
|
28
28
|
}
|
|
29
29
|
|