@lexho111/plainblog 0.1.1 → 0.1.2

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/Blog.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import http from "http";
2
2
  import fs from "fs";
3
3
  import { URLSearchParams } from "url";
4
+ import { Readable, Transform, Writable, pipeline } from "stream";
5
+ import { MapTransform } from "./streams.js";
4
6
  import { fromEvent, firstValueFrom } from "rxjs";
5
7
  import { map, scan, takeUntil, last, defaultIfEmpty } from "rxjs/operators";
6
8
  import Article from "./Article.js";
@@ -165,7 +167,8 @@ export default class Blog {
165
167
  } else if (req.method === "GET" && req.url === "/") {
166
168
  // load articles
167
169
 
168
- //this.loadScripts(); this.loadStyles();
170
+ // reload styles and scripts on (every) request
171
+ this.loadScripts(); this.loadStyles();
169
172
 
170
173
  const html = await this.toHTML(); // render this blog to HTML
171
174
  res.writeHead(200, { "Content-Type": "text/html; charset=UTF-8" });
@@ -290,19 +293,58 @@ export default class Blog {
290
293
  title: this.title,
291
294
  articles: this.articles,
292
295
  };
293
- const markdown = formatMarkdown(data);
294
- console.log(markdown);
296
+ //const markdown = formatMarkdown(data);
297
+
298
+ return new Promise((resolve, reject) => {
299
+ let markdownResult = "";
300
+ pipeline(
301
+ Readable.from([data]),
302
+ new MapTransform((chunk) => formatMarkdown(chunk, this.scripts, this.styles)),
303
+ new Writable({
304
+ write(chunk, encoding, callback) {
305
+ markdownResult += chunk.toString();
306
+ callback();
307
+ },
308
+ }),
309
+ (err) => {
310
+ if (err) reject(err);
311
+ else {
312
+ console.log(markdownResult)
313
+ resolve(markdownResult);
314
+ }
315
+ }
316
+ );
317
+ });
295
318
  }
296
319
 
297
320
  /** render this blog content to valid html */
298
- toHTML() {
321
+ async toHTML() {
299
322
  const data = {
300
323
  title: this.title,
301
324
  articles: this.articles,
302
325
  };
303
-
304
- const html = formatHTML(data, this.scripts, this.styles);
305
- if (validate(html)) return html;
306
- else throw new Error("Error. Invalid HTML!");
326
+
327
+ return new Promise((resolve, reject) => {
328
+ let htmlResult = "";
329
+ pipeline(
330
+ Readable.from([data]),
331
+ new MapTransform((chunk) => formatHTML(chunk, this.scripts, this.styles)),
332
+ new MapTransform((chunk) => {
333
+ const html = chunk.toString();
334
+ if (validate(html)) return html;
335
+ throw new Error("Error. Invalid HTML!");
336
+ }),
337
+ new Writable({
338
+ write(chunk, encoding, callback) {
339
+ htmlResult += chunk.toString();
340
+ callback();
341
+ },
342
+ }),
343
+ (err) => {
344
+ if (err) reject(err);
345
+ else resolve(htmlResult);
346
+ }
347
+ );
348
+ });
307
349
  }
308
350
  }
package/Formatter.js CHANGED
@@ -1,7 +1,8 @@
1
1
  /** format content to html */
2
2
  export function formatHTML(data, script, style) {
3
3
  //export function formatHTML(data) {
4
- const button = `<button type="button" onClick="fillWithContent();" style="margin: 4px;">generate random text</button>`;
4
+ //const button = `<button type="button" onClick="fillWithContent();" style="margin: 4px;">generate random text</button>`;
5
+ const button = "";
5
6
  return `<!DOCTYPE html>
6
7
  <html lang="de">
7
8
  <head>
@@ -22,15 +23,17 @@ export function formatHTML(data, script, style) {
22
23
  </script>
23
24
  </form>
24
25
  <hr>
26
+ <section class="grid">
25
27
  ${data.articles
26
28
  .map(
27
29
  (article) => `
28
- <article style="overflow-wrap: break-word;">
30
+ <article>
29
31
  <h2>${article.title}</h2>
30
32
  <p>${article.getContentShort()}</p>
31
33
  </article>`
32
34
  )
33
35
  .join("")}
36
+ <section
34
37
  </div>
35
38
  </body>
36
39
  </html>`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexho111/plainblog",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A tool for creating and serving a minimalist, single-page blog.",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/scripts.min.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! gruntproject 2025-12-21 */
1
+ /*! gruntproject 2025-12-22 */
2
2
  function generateRandomContent(t){let n="";for(let e=0;e<t;e++){var o=Math.random()*("z".charCodeAt(0)-"A".charCodeAt(0)),o=String.fromCharCode("A".charCodeAt(0)+o);n+=o}return n}function fillWithContent(){var e=document.getElementById("title");document.getElementById("content").value=generateRandomContent(200),e.value=generateRandomContent(50)}
@@ -0,0 +1 @@
1
+ function test(){console.log("123")}
package/streams.js ADDED
@@ -0,0 +1,17 @@
1
+ import { Transform } from "stream";
2
+
3
+ export class MapTransform extends Transform {
4
+ constructor(fn) {
5
+ super({
6
+ objectMode: true,
7
+ transform: (chunk, encoding, callback) => {
8
+ try {
9
+ // Call the mapping function with the chunk
10
+ callback(null, fn(chunk));
11
+ } catch (err) {
12
+ callback(err);
13
+ }
14
+ },
15
+ });
16
+ }
17
+ }
package/styles.min.css CHANGED
@@ -1 +1,2 @@
1
- body{font-family:Courier;background-color:#d3d3d3}div{color:#000;width:500px}h1,h2,h3{font-weight:700}
1
+ .alert{border:1px solid rgba(198,83,140,.88)}.grid{border:0 solid #000;display:grid;gap:.25rem;grid-template-columns:1fr}.grid article{border:0 solid #ccc;border-radius:4px;min-width:0;overflow-wrap:break-word;padding:.25rem}body{background-color:orange;font-family:Arial}
2
+ /*# sourceMappingURL=styles.min.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["styles-compiled.css","styles.css"],"names":[],"mappings":"AAAA,OACA,qCACA,CAEA,MAIA,mBAAA,CAHA,YAAA,CAEA,UAAA,CADA,yBAGA,CACA,cAEA,mBAAA,CACA,iBAAA,CACA,WAAA,CACA,wBAAA,CAJA,cAKA,CChBA,KACA,uBAAA,CACA,iBACA","file":"styles.min.css","sourcesContent":[".alert {\n border: 1px solid rgba(198, 83, 140, 0.88);\n}\n\n.grid {\n display: grid;\n grid-template-columns: 1fr;\n gap: 0.25rem;\n border: 0px solid black;\n}\n.grid article {\n padding: 0.25rem;\n border: 0px solid #ccc;\n border-radius: 4px;\n min-width: 0; /* Allow grid items to shrink */\n overflow-wrap: break-word; /* Break long words */\n}","body {\n background-color: orange;\n font-family: Arial;\n}\n"]}
@@ -74,6 +74,6 @@ describe("server test", () => {
74
74
  const responseData = await response.json();
75
75
  expect(responseData).toEqual(newArticle);
76
76
 
77
- expect(blog.toHTML()).toContain(newArticle.content); // does blog contain my new article?
77
+ expect(await blog.toHTML()).toContain(newArticle.content); // does blog contain my new article?
78
78
  });
79
79
  });