diagram-2020 0.0.1

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 ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "diagram-2020",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "scripts": {
6
+ "start": "node server.js"
7
+ },
8
+ "bin": {
9
+ "diagram": "server.js"
10
+ },
11
+ "dependencies": {
12
+ "chokidar": "^3.6.0",
13
+ "express": "^4.19.2",
14
+ "livereload": "^0.9.3",
15
+ "connect-livereload": "^0.6.1",
16
+ "node-fetch": "^3.3.2"
17
+ }
18
+ }
package/server.js ADDED
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import fetch from "node-fetch";
5
+ import chokidar from "chokidar";
6
+ import express from "express";
7
+ import livereload from "livereload";
8
+ import connectLiveReload from "connect-livereload";
9
+
10
+ const PORT = 3000;
11
+ const MERMAID_URL =
12
+ "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js";
13
+
14
+ const MERMAID_FILE = "mermaid.min.js";
15
+ const DIAGRAM_FILE = "diagram.txt";
16
+ const HTML_FILE = "index.html";
17
+
18
+ function humanize(text) {
19
+ return text
20
+ .replace(/([A-Z])/g, " $1")
21
+ .replace(/_/g, " ")
22
+ .toLowerCase()
23
+ .trim();
24
+ }
25
+
26
+ function processDiagram(raw) {
27
+ const lines = raw
28
+ .split("\n")
29
+ .map(l => l.trim())
30
+ .filter(Boolean);
31
+
32
+ const groups = {};
33
+ const relations = [];
34
+
35
+ for (const line of lines) {
36
+ relations.push(line);
37
+
38
+ const nodes = line
39
+ .replace(/:.+$/, "")
40
+ .split("-->")
41
+ .map(s => s.trim());
42
+
43
+ for (const node of nodes) {
44
+ const [group, state] = node.split("_");
45
+ if (!group || !state) continue;
46
+
47
+ if (!groups[group]) {
48
+ groups[group] = new Set();
49
+ }
50
+ groups[group].add(node);
51
+ }
52
+ }
53
+
54
+ let output = [];
55
+ output.push("stateDiagram-v2");
56
+
57
+ // group labels
58
+ for (const group of Object.keys(groups)) {
59
+ output.push(`${group}: ${humanize(group)}`);
60
+ }
61
+
62
+ // group states
63
+ for (const [group, states] of Object.entries(groups)) {
64
+ output.push(`state ${group} {`);
65
+ for (const full of states) {
66
+ const label = full.split("_")[1];
67
+ output.push(` ${full}: ${humanize(label)}`);
68
+ }
69
+ output.push("}");
70
+ }
71
+
72
+ // relations
73
+ output.push(...relations);
74
+
75
+ return output.join("\n");
76
+ }
77
+
78
+
79
+ /* =========================
80
+ 1. DOWNLOAD MERMAID JS
81
+ ========================= */
82
+ async function ensureMermaid() {
83
+ if (fs.existsSync(MERMAID_FILE)) {
84
+ console.log("✅ mermaid.min.js sudah ada");
85
+ return;
86
+ }
87
+
88
+ console.log("⬇️ Downloading mermaid.min.js...");
89
+ const res = await fetch(MERMAID_URL);
90
+ const text = await res.text();
91
+ fs.writeFileSync(MERMAID_FILE, text);
92
+ console.log("✅ mermaid.min.js berhasil di-download");
93
+ }
94
+
95
+ /* =========================
96
+ 2. GENERATE HTML
97
+ ========================= */
98
+ function generateHTML() {
99
+ let diagram = fs.existsSync(DIAGRAM_FILE)
100
+ ? fs.readFileSync(DIAGRAM_FILE, "utf8")
101
+ : "";
102
+
103
+ diagram = processDiagram(diagram)
104
+
105
+ const html = `<!DOCTYPE html>
106
+ <html lang="en">
107
+ <head>
108
+ <meta charset="UTF-8" />
109
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
110
+ <title>Mermaid Preview</title>
111
+ <script src="./mermaid.min.js"></script>
112
+ <script>
113
+ mermaid.initialize({ startOnLoad: true });
114
+ </script>
115
+ <style>
116
+ body {
117
+ font-family: sans-serif;
118
+ padding: 20px;
119
+ }
120
+ </style>
121
+ </head>
122
+ <body>
123
+ <div class="mermaid">
124
+ ${diagram}
125
+ </div>
126
+ </body>
127
+ </html>`;
128
+
129
+ fs.writeFileSync(HTML_FILE, html);
130
+ console.log("🔄 index.html updated");
131
+ }
132
+
133
+ /* =========================
134
+ 3. LIVE RELOAD SERVER
135
+ ========================= */
136
+ const liveReloadServer = livereload.createServer();
137
+ liveReloadServer.watch(process.cwd());
138
+
139
+ const app = express();
140
+ app.use(connectLiveReload());
141
+ app.use(express.static(process.cwd()));
142
+
143
+ app.listen(PORT, () => {
144
+ console.log(`🚀 Static server running at http://localhost:${PORT}`);
145
+ });
146
+
147
+ /* =========================
148
+ 4. WATCH FILE
149
+ ========================= */
150
+ async function main() {
151
+ await ensureMermaid();
152
+ generateHTML();
153
+
154
+ chokidar.watch(DIAGRAM_FILE).on("change", () => {
155
+ console.log("✏️ diagram.txt changed");
156
+ generateHTML();
157
+ liveReloadServer.refresh("/");
158
+ });
159
+ }
160
+
161
+ main();