@kenjura/ursa 0.10.0 → 0.33.0

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/src/serve.js CHANGED
@@ -1,29 +1,135 @@
1
1
  import express from "express";
2
2
  import watch from "node-watch";
3
-
4
3
  import { generate } from "./jobs/generate.js";
5
4
  import { join, resolve } from "path";
5
+ import fs from "fs";
6
+ import { promises } from "fs";
7
+ const { readdir } = promises;
8
+
9
+ /**
10
+ * Configurable serve function for CLI and library use
11
+ */
12
+ export async function serve({
13
+ _source,
14
+ _meta,
15
+ _output,
16
+ port = 8080,
17
+ _whitelist = null,
18
+ _clean = false
19
+ } = {}) {
20
+ const sourceDir = resolve(_source);
21
+ const metaDir = resolve(_meta);
22
+ const outputDir = resolve(_output);
6
23
 
7
- const source = resolve(process.env.SOURCE ?? join(process.cwd(), "source"));
8
- const meta = resolve(process.env.META ?? join(process.cwd(), "meta"));
9
- const output = resolve(process.env.OUTPUT ?? join(process.cwd(), "build"));
24
+ console.log({ source: sourceDir, meta: metaDir, output: outputDir, port, whitelist: _whitelist, clean: _clean });
10
25
 
11
- console.log({ source, meta, output });
26
+ // Initial generation (use _clean flag only for initial generation)
27
+ console.log("Generating initial site...");
28
+ await generate({ _source: sourceDir, _meta: metaDir, _output: outputDir, _whitelist, _clean });
29
+ console.log("Initial generation complete. Starting server...");
12
30
 
13
- await generate({ source, meta, output });
14
- console.log("done generating. now serving...");
31
+ // Start file server
32
+ serveFiles(outputDir, port);
15
33
 
16
- serve(output);
34
+ // Watch for changes
35
+ console.log("Watching for file changes...");
36
+
37
+ // Meta changes trigger full rebuild (templates, CSS, etc. affect all pages)
38
+ watch(metaDir, { recursive: true, filter: /\.(js|json|css|html|md|txt|yml|yaml)$/ }, async (evt, name) => {
39
+ console.log(`Meta files changed! Event: ${evt}, File: ${name}`);
40
+ console.log("Full rebuild required (meta files affect all pages)...");
41
+ try {
42
+ await generate({ _source: sourceDir, _meta: metaDir, _output: outputDir, _whitelist, _clean: true });
43
+ console.log("Regeneration complete.");
44
+ } catch (error) {
45
+ console.error("Error during regeneration:", error.message);
46
+ }
47
+ });
17
48
 
18
- watch(meta, { recursive: true }, async (evt, name) => {
19
- console.log("meta files changed! generating output");
20
- await generate({ source, meta, output });
21
- });
49
+ // Source changes use incremental mode (only regenerate changed files)
50
+ // Exception: CSS changes require full rebuild since they're embedded in all pages
51
+ watch(sourceDir, { recursive: true, filter: /\.(js|json|css|html|md|txt|yml|yaml)$/ }, async (evt, name) => {
52
+ console.log(`Source files changed! Event: ${evt}, File: ${name}`);
53
+
54
+ // CSS files affect all pages (embedded styles), so trigger full rebuild
55
+ const isCssChange = name && name.endsWith('.css');
56
+ if (isCssChange) {
57
+ console.log("CSS change detected - full rebuild required...");
58
+ try {
59
+ await generate({ _source: sourceDir, _meta: metaDir, _output: outputDir, _whitelist, _clean: true });
60
+ console.log("Regeneration complete.");
61
+ } catch (error) {
62
+ console.error("Error during regeneration:", error.message);
63
+ }
64
+ } else {
65
+ console.log("Incremental rebuild...");
66
+ try {
67
+ await generate({ _source: sourceDir, _meta: metaDir, _output: outputDir, _whitelist });
68
+ console.log("Regeneration complete.");
69
+ } catch (error) {
70
+ console.error("Error during regeneration:", error.message);
71
+ }
72
+ }
73
+ });
22
74
 
23
- watch(source, { recursive: true }, async (evt, name) => {
24
- console.log("source files changed! generating output");
25
- await generate({ source, meta, output });
26
- });
75
+ console.log(`🚀 Development server running at http://localhost:${port}`);
76
+ console.log("📁 Serving files from:", outputDir);
77
+ console.log("👀 Watching for changes in:");
78
+ console.log(" Source:", sourceDir, "(incremental)");
79
+ console.log(" Meta:", metaDir, "(full rebuild)");
80
+ console.log("\nPress Ctrl+C to stop the server");
81
+ }
82
+
83
+ /**
84
+ * Start HTTP server to serve static files
85
+ */
86
+ function serveFiles(outputDir, port = 8080) {
87
+ const app = express();
88
+
89
+ app.use(
90
+ express.static(outputDir, { extensions: ["html"], index: "index.html" })
91
+ );
92
+
93
+ app.get("/", async (req, res) => {
94
+ try {
95
+ console.log({ output: outputDir });
96
+ const dir = await readdir(outputDir);
97
+ const html = `
98
+ <!DOCTYPE html>
99
+ <html>
100
+ <head>
101
+ <title>Ursa Development Server</title>
102
+ <style>
103
+ body { font-family: Arial, sans-serif; margin: 40px; }
104
+ h1 { color: #333; }
105
+ ul { list-style-type: none; padding: 0; }
106
+ li { margin: 8px 0; }
107
+ a { color: #0066cc; text-decoration: none; }
108
+ a:hover { text-decoration: underline; }
109
+ </style>
110
+ </head>
111
+ <body>
112
+ <h1>Ursa Development Server</h1>
113
+ <p>Files in ${outputDir}:</p>
114
+ <ul>
115
+ ${dir
116
+ .map((file) => `<li><a href="${file}">${file}</a></li>`)
117
+ .join("")}
118
+ </ul>
119
+ </body>
120
+ </html>
121
+ `;
122
+ res.setHeader("Content-Type", "text/html");
123
+ res.send(html);
124
+ } catch (error) {
125
+ res.status(500).send("Error reading directory");
126
+ }
127
+ });
128
+
129
+ app.listen(port, () => {
130
+ console.log(`🌐 Server listening on port ${port}`);
131
+ });
132
+ }
27
133
 
28
134
  /**
29
135
  * we're only interested in meta (and maybe, in the future, source)
@@ -39,31 +145,26 @@ function filter(filename, skip) {
39
145
  return false;
40
146
  }
41
147
 
42
- import fs, { stat } from "fs";
43
- import { promises } from "fs";
44
- const { readdir } = promises;
45
- import http from "http";
46
- import { Server } from "node-static";
148
+ // Default serve function for backward compatibility (only run when executed directly)
149
+ if (import.meta.url === `file://${process.argv[1]}`) {
150
+ const source = resolve(process.env.SOURCE ?? join(process.cwd(), "source"));
151
+ const meta = resolve(process.env.META ?? join(process.cwd(), "meta"));
152
+ const output = resolve(process.env.OUTPUT ?? join(process.cwd(), "build"));
47
153
 
48
- function serve(root) {
49
- const app = express();
50
- const port = process.env.PORT || 8080;
154
+ console.log({ source, meta, output });
51
155
 
52
- app.use(
53
- express.static(output, { extensions: ["html"], index: "index.html" })
54
- );
156
+ await generate({ _source: source, _meta: meta, _output: output });
157
+ console.log("done generating. now serving...");
55
158
 
56
- app.get("/", async (req, res) => {
57
- console.log({ output });
58
- const dir = await readdir(output);
59
- const html = dir
60
- .map((file) => `<li><a href="${file}">${file}</a></li>`)
61
- .join("");
62
- res.setHeader("Content-Type", "text/html");
63
- res.send(html);
159
+ serveFiles(output);
160
+
161
+ watch(meta, { recursive: true }, async (evt, name) => {
162
+ console.log("meta files changed! generating output");
163
+ await generate({ _source: source, _meta: meta, _output: output });
64
164
  });
65
165
 
66
- app.listen(port, () => {
67
- console.log(`server listening on port ${port}`);
166
+ watch(source, { recursive: true }, async (evt, name) => {
167
+ console.log("source files changed! generating output");
168
+ await generate({ _source: source, _meta: meta, _output: output });
68
169
  });
69
170
  }
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- 16.18
@@ -1,20 +0,0 @@
1
- {
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- "version": "0.2.0",
6
- "configurations": [
7
- {
8
- "type": "node",
9
- "request": "launch",
10
- "name": "Launch Program",
11
- "skipFiles": [
12
- "<node_internals>/**"
13
- ],
14
- "env": {
15
- "INCLUDE_FILTER": "Kaine",
16
- },
17
- "program": "${workspaceFolder}/src/serve.js"
18
- }
19
- ]
20
- }
package/TODO.md DELETED
@@ -1,16 +0,0 @@
1
- # Basic Functionality
2
-
3
- - [x] Enable static assets from meta in build (perhaps by copying them?)
4
- - [x] Enable static assets from source in build
5
- - [ ] Handle menus at different levels
6
- - [x] Add a live-serve command that translates from source in real time (for testing)
7
- - [ ] Deal with crashes when no menu file is found
8
-
9
-
10
- # Wikitext
11
- - [ ] Support original site styles
12
- - [ ] Support original menu
13
- - [ ] Fix links
14
-
15
- # Mobile UI
16
- - [ ] Konsta UI
package/nodemon.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "restartable": "rs",
3
- "ignore": [".git", "node_modules/**/node_modules", "build"],
4
- "verbose": true,
5
- "execMap": {
6
- "js": "node --harmony"
7
- },
8
- "events": {
9
- "restart": "osascript -e 'display notification \"App restarted due to:\n'$FILENAME'\" with title \"nodemon\"'"
10
- },
11
- "watch": ["src/", "docs/"],
12
- "env": {
13
- "NODE_ENV": "development"
14
- },
15
- "ext": "js,json,css,cjs,mjs,ts,tsx,html"
16
- }