@pajh/buldng 0.0.4 → 0.0.5

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 ADDED
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env node
2
+ // serve.js
3
+ import http from "node:http";
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import { exec } from "node:child_process";
7
+ import MIME from "./MIME.json" with { type: "json" };
8
+
9
+ import {
10
+ createState,
11
+ initHotReload,
12
+ initDevErrors,
13
+ handleHttpRequest,
14
+ processArgs,
15
+ registerInject,
16
+ sanitiseRoot,
17
+ sanitisePort,
18
+ local,
19
+ ARGS
20
+ } from "./serve-lib.js";
21
+
22
+ // --------------------------------------------------
23
+ // CONFIG + STATIC DATA
24
+ // --------------------------------------------------
25
+
26
+ const DEFAULT_PORT = 5173;
27
+ const DEFAULT_ROOT = "dist";
28
+
29
+ // --------------------------------------------------
30
+ // HTML INJECTIONS
31
+ // --------------------------------------------------
32
+
33
+ function registerHtmlInjections(state) {
34
+
35
+ if (state.DEV_ERRORS) {
36
+ console.log("[dev-errors] creating injection for dev-errors.js");
37
+
38
+ // add mapping entry
39
+ state.MAPPINGS.push({
40
+ from: "/dev-errors.js",
41
+ to: "buldng://dev-errors.js",
42
+ type: "file"
43
+ });
44
+
45
+ registerInject(state, "html", "<!--POSTLAYOUT-->", `
46
+ <script type="module" src="/dev-errors.js"></script>
47
+ `, "post");
48
+ }
49
+
50
+ if (state.hotEnabled) {
51
+ registerInject(state, "html", "</head>", `
52
+ <script>
53
+ const es = new EventSource("/__hot");
54
+ es.onmessage = () => location.reload();
55
+ </script>
56
+ `, "pre");
57
+ }
58
+ }
59
+
60
+
61
+ // --------------------------------------------------
62
+ // INITIALIZATION
63
+ // --------------------------------------------------
64
+
65
+ function init() {
66
+
67
+ processArgs();
68
+ let ROOT = ARGS.get("root");
69
+ let PORT = ARGS.get("port");
70
+
71
+ if (!ROOT) {
72
+ ROOT = DEFAULT_ROOT;
73
+ console.log(`[args] root: ${ROOT} (DEFAULT)`);
74
+ } else {
75
+ console.log(`[args] root: ${ROOT}`);
76
+ }
77
+
78
+ ROOT = sanitiseRoot(ROOT);
79
+
80
+ if (!PORT) {
81
+ PORT = DEFAULT_PORT;
82
+ console.log(`[args] port: ${PORT} (DEFAULT)`);
83
+ } else {
84
+ console.log(`[args] port: ${PORT}`);
85
+ }
86
+
87
+ PORT = sanitisePort(PORT);
88
+
89
+ const state = createState({
90
+ ROOT: ROOT,
91
+ PORT: PORT,
92
+ MAPPINGS: [],
93
+ MIME: MIME,
94
+ LOG_ALL: ARGS.get("log"),
95
+ HOT_REQUESTED: ARGS.get("hot"),
96
+ DEV_ERRORS: ARGS.get("dev-errors")
97
+ });
98
+
99
+ loadMappings(state);
100
+ initHotReload(state);
101
+ initDevErrors(state);
102
+ registerHtmlInjections(state);
103
+
104
+ return state;
105
+ }
106
+
107
+ function loadMappings(state) {
108
+ const mapPath = ARGS.get("map");
109
+
110
+ if (!mapPath) {
111
+ console.log("[map] OFF");
112
+ state.MAPPINGS = [];
113
+ return;
114
+ }
115
+
116
+ try {
117
+ const full = path.resolve(mapPath);
118
+ const json = JSON.parse(fs.readFileSync(full, "utf8"));
119
+ state.MAPPINGS = json;
120
+ console.log(`[map] ${full} (${json.length} rules)`);
121
+ } catch (err) {
122
+ console.log(`[map] FAILED to load ${mapPath}`);
123
+ process.exit(13);
124
+ }
125
+ }
126
+
127
+
128
+ // --------------------------------------------------
129
+ // SERVE LOOP (VISIBLE SKELETON)
130
+ // --------------------------------------------------
131
+
132
+ function serve(state) {
133
+ const server = http.createServer((req, res) => {
134
+ // -----------------------------
135
+ // The bones of the loop stay here
136
+ // -----------------------------
137
+
138
+ state.running = true;
139
+
140
+ // 1. Receive request
141
+ const urlPath = req.url;
142
+
143
+ // 2. Delegate to serve-lib.js to produce a response object
144
+ const response = handleHttpRequest(urlPath, req, state);
145
+
146
+ // 3. Send response
147
+ response.send(res);
148
+ });
149
+
150
+ process.on("SIGTERM", () => {
151
+ // clean shutdown logic
152
+ server.close(() => {
153
+ process.exit(0);
154
+ });
155
+ });
156
+
157
+ // Optional graceful shutdown
158
+ process.on("SIGINT", () => {
159
+ teardown(state);
160
+ server.close(() => process.exit(0));
161
+ });
162
+
163
+ server.listen(state.PORT, () => {
164
+ console.log(`[serve] root: ${state.ROOT} at http://localhost:${state.PORT}`);
165
+ const browser = ARGS.get("browser");
166
+ if (browser)
167
+ exec(`${browser} http://localhost:${state.PORT}`);
168
+ });
169
+
170
+ return server;
171
+ }
172
+
173
+ // --------------------------------------------------
174
+ // TEARDOWN
175
+ // --------------------------------------------------
176
+
177
+ function teardown(state) {
178
+ state.running = false;
179
+ console.log("Server shutting down.");
180
+ }
181
+
182
+ // --------------------------------------------------
183
+ // MAIN
184
+ // --------------------------------------------------
185
+
186
+ function main() {
187
+ const state = init();
188
+ const server = serve(state);
189
+
190
+
191
+ }
192
+
193
+ main();
@@ -6,5 +6,14 @@ declare global {
6
6
  a: Promise<void>;
7
7
  _resolveA: () => void;
8
8
  };
9
+
10
+ __error_handler?: (
11
+ event: ErrorEvent | PromiseRejectionEvent,
12
+ page: string
13
+ ) => void;
14
+
15
+ __buldngErrorOverlay?: boolean;
16
+
17
+ __buldng_listenersInstalled?: boolean;
9
18
  }
10
19
  }
package/src/wrapper.html CHANGED
@@ -13,6 +13,7 @@
13
13
  window.__ready.a = new Promise((resolve) => { window.__ready._resolveA = resolve; });
14
14
  </script>
15
15
  <script type="module" src="/layout.js"></script>
16
+ <!--POSTLAYOUT-->
16
17
  <!--SCRIPTS-->
17
18
  </head>
18
19
  <body>
@@ -20,5 +21,6 @@
20
21
  <!-- Project outline (camera-style) will be stitched here -->
21
22
  <!--CAMERA-STYLE-->
22
23
  </div>
24
+ <div id="b-modal-root"></div>
23
25
  </body>
24
26
  </html>
@@ -1,84 +0,0 @@
1
- // Development-only error overlay installed by the local preview server.
2
- // The production build never references this file from its HTML.
3
-
4
- window.__buldngErrorOverlay = true;
5
-
6
- let shown = false;
7
-
8
- window.addEventListener("error", (event) => {
9
- showError(event.error ?? event.message, "error");
10
- });
11
-
12
- window.addEventListener("unhandledrejection", (event) => {
13
- showError(event.reason, "unhandledrejection");
14
- });
15
-
16
- function showError(reason, type) {
17
- if (shown) return;
18
- shown = true;
19
-
20
- const message = getMessage(reason);
21
- const stack = getStack(reason);
22
- const overlay = document.createElement("aside");
23
- overlay.id = "buldng-dev-error-overlay";
24
- overlay.style.cssText = [
25
- "position: fixed",
26
- "z-index: 2147483647",
27
- "left: 1rem",
28
- "right: 1rem",
29
- "bottom: 1rem",
30
- "max-height: 70vh",
31
- "overflow: auto",
32
- "padding: 1rem 1.25rem",
33
- "border: 2px solid #d33",
34
- "border-radius: 8px",
35
- "background: #240b0b",
36
- "color: #fff",
37
- "font: 16px/1.4 monospace",
38
- "box-shadow: 0 4px 24px #0008",
39
- ].join(";");
40
-
41
- const close = document.createElement("button");
42
- close.type = "button";
43
- close.textContent = "Close";
44
- close.style.cssText = "float:right; padding:.35rem .6rem; cursor:pointer";
45
- close.addEventListener("click", () => overlay.remove());
46
-
47
- const title = document.createElement("strong");
48
- title.textContent = "BULDR preview: something broke";
49
-
50
- const hint = document.createElement("p");
51
- hint.textContent = `(${type}) Check the DevTools console for the full mapped stack.`;
52
-
53
- const text = document.createElement("p");
54
- text.textContent = message;
55
-
56
- overlay.append(close, title, hint, text);
57
- if (stack) {
58
- const details = document.createElement("details");
59
- const summary = document.createElement("summary");
60
- summary.textContent = "Raw stack";
61
- const pre = document.createElement("pre");
62
- pre.textContent = stack;
63
- pre.style.cssText = "white-space:pre-wrap; overflow-wrap:anywhere";
64
- details.append(summary, pre);
65
- overlay.appendChild(details);
66
- }
67
-
68
- document.body?.appendChild(overlay);
69
- }
70
-
71
- function getMessage(reason) {
72
- if (reason instanceof Error && reason.message) return reason.message;
73
- if (typeof reason === "string" && reason) return reason;
74
- try {
75
- const text = JSON.stringify(reason);
76
- return text || "Unknown error";
77
- } catch {
78
- return String(reason) || "Unknown error";
79
- }
80
- }
81
-
82
- function getStack(reason) {
83
- return reason && typeof reason.stack === "string" ? reason.stack : "";
84
- }