elegance-js 2.1.7 → 2.1.9

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/dist/build.mjs CHANGED
@@ -1,10 +1,1237 @@
1
- // src/build.ts
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // src/shared/serverElements.ts
12
+ var createBuildableElement, createChildrenlessBuildableElement, childrenlessElementTags, elementTags, elements, childrenlessElements, allElements;
13
+ var init_serverElements = __esm({
14
+ "src/shared/serverElements.ts"() {
15
+ "use strict";
16
+ createBuildableElement = (tag) => {
17
+ return (options3, ...children) => ({
18
+ tag,
19
+ options: options3 || {},
20
+ children
21
+ });
22
+ };
23
+ createChildrenlessBuildableElement = (tag) => {
24
+ return (options3) => ({
25
+ tag,
26
+ options: options3 || {},
27
+ children: null
28
+ });
29
+ };
30
+ childrenlessElementTags = [
31
+ "area",
32
+ "base",
33
+ "br",
34
+ "col",
35
+ "embed",
36
+ "hr",
37
+ "img",
38
+ "input",
39
+ "link",
40
+ "meta",
41
+ "source",
42
+ "track",
43
+ "path",
44
+ "rect"
45
+ ];
46
+ elementTags = [
47
+ "a",
48
+ "address",
49
+ "article",
50
+ "aside",
51
+ "audio",
52
+ "blockquote",
53
+ "body",
54
+ "button",
55
+ "canvas",
56
+ "caption",
57
+ "colgroup",
58
+ "data",
59
+ "datalist",
60
+ "dd",
61
+ "del",
62
+ "details",
63
+ "dialog",
64
+ "div",
65
+ "dl",
66
+ "dt",
67
+ "fieldset",
68
+ "figcaption",
69
+ "figure",
70
+ "footer",
71
+ "form",
72
+ "h1",
73
+ "h2",
74
+ "h3",
75
+ "h4",
76
+ "h5",
77
+ "h6",
78
+ "head",
79
+ "header",
80
+ "hgroup",
81
+ "html",
82
+ "iframe",
83
+ "ins",
84
+ "label",
85
+ "legend",
86
+ "li",
87
+ "main",
88
+ "map",
89
+ "meter",
90
+ "nav",
91
+ "noscript",
92
+ "object",
93
+ "ol",
94
+ "optgroup",
95
+ "option",
96
+ "output",
97
+ "p",
98
+ "picture",
99
+ "pre",
100
+ "progress",
101
+ "q",
102
+ "section",
103
+ "select",
104
+ "summary",
105
+ "table",
106
+ "tbody",
107
+ "td",
108
+ "template",
109
+ "textarea",
110
+ "tfoot",
111
+ "th",
112
+ "thead",
113
+ "time",
114
+ "tr",
115
+ "ul",
116
+ "video",
117
+ "span",
118
+ "script",
119
+ "abbr",
120
+ "b",
121
+ "bdi",
122
+ "bdo",
123
+ "cite",
124
+ "code",
125
+ "dfn",
126
+ "em",
127
+ "i",
128
+ "kbd",
129
+ "mark",
130
+ "rp",
131
+ "rt",
132
+ "ruby",
133
+ "s",
134
+ "samp",
135
+ "small",
136
+ "strong",
137
+ "sub",
138
+ "sup",
139
+ "u",
140
+ "wbr",
141
+ "title",
142
+ "svg"
143
+ ];
144
+ elements = {};
145
+ childrenlessElements = {};
146
+ for (const element of elementTags) {
147
+ elements[element] = createBuildableElement(element);
148
+ }
149
+ for (const element of childrenlessElementTags) {
150
+ childrenlessElements[element] = createChildrenlessBuildableElement(element);
151
+ }
152
+ allElements = {
153
+ ...elements,
154
+ ...childrenlessElements
155
+ };
156
+ }
157
+ });
158
+
159
+ // src/shared/bindServerElements.ts
160
+ var init_bindServerElements = __esm({
161
+ "src/shared/bindServerElements.ts"() {
162
+ "use strict";
163
+ init_serverElements();
164
+ Object.assign(globalThis, elements);
165
+ Object.assign(globalThis, childrenlessElements);
166
+ }
167
+ });
168
+
169
+ // src/server/render.ts
170
+ var renderRecursively, serverSideRenderPage;
171
+ var init_render = __esm({
172
+ "src/server/render.ts"() {
173
+ "use strict";
174
+ init_bindServerElements();
175
+ renderRecursively = (element) => {
176
+ let returnString = "";
177
+ if (typeof element === "boolean") return returnString;
178
+ else if (typeof element === "number" || typeof element === "string") {
179
+ return returnString + element;
180
+ } else if (Array.isArray(element)) {
181
+ return returnString + element.join(", ");
182
+ }
183
+ returnString += `<${element.tag}`;
184
+ if (typeof element.options === "object") {
185
+ const {
186
+ tag: elementTag,
187
+ options: elementOptions,
188
+ children: elementChildren
189
+ } = element.options;
190
+ if (elementTag !== void 0 && elementOptions !== void 0 && elementChildren !== void 0) {
191
+ const children = element.children;
192
+ element.children = [
193
+ element.options,
194
+ ...children
195
+ ];
196
+ element.options = {};
197
+ } else {
198
+ for (const [attrName, attrValue] of Object.entries(element.options)) {
199
+ if (typeof attrValue === "object") {
200
+ throw `Attr ${attrName}, for element ${element.tag} has obj type. Got: ${JSON.stringify(element, null, 2)}`;
201
+ }
202
+ returnString += ` ${attrName.toLowerCase()}="${attrValue}"`;
203
+ }
204
+ }
205
+ } else if (typeof element.options !== "object" && element.options !== void 0) {
206
+ element.children = [element.options, ...element.children || []];
207
+ }
208
+ if (element.children === null) {
209
+ returnString += "/>";
210
+ return returnString;
211
+ }
212
+ returnString += ">";
213
+ for (const child2 of element.children) {
214
+ returnString += renderRecursively(child2);
215
+ }
216
+ returnString += `</${element.tag}>`;
217
+ return returnString;
218
+ };
219
+ serverSideRenderPage = async (page, pathname) => {
220
+ if (!page) {
221
+ throw `No Page Provided.`;
222
+ }
223
+ if (typeof page === "function") {
224
+ throw `Unbuilt page provided to ssr page.`;
225
+ }
226
+ const bodyHTML = renderRecursively(page);
227
+ return {
228
+ bodyHTML
229
+ };
230
+ };
231
+ }
232
+ });
233
+
234
+ // src/server/generateHTMLTemplate.ts
235
+ var generateHTMLTemplate;
236
+ var init_generateHTMLTemplate = __esm({
237
+ "src/server/generateHTMLTemplate.ts"() {
238
+ "use strict";
239
+ init_render();
240
+ generateHTMLTemplate = async ({
241
+ pageURL,
242
+ head: head2,
243
+ serverData = null,
244
+ addPageScriptTag = true,
245
+ name,
246
+ requiredClientModules = {},
247
+ environment
248
+ }) => {
249
+ let StartTemplate = `<meta name="viewport" content="width=device-width, initial-scale=1.0">`;
250
+ if (environment === "production") {
251
+ StartTemplate += `<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">`;
252
+ }
253
+ StartTemplate += '<meta charset="UTF-8">';
254
+ for (const [globalName] of Object.entries(requiredClientModules)) {
255
+ StartTemplate += `<script data-module="true" src="/shipped/${globalName}.js" defer="true"></script>`;
256
+ }
257
+ if (addPageScriptTag === true) {
258
+ const sanitized = pageURL === "" ? "/" : `/${pageURL}`;
259
+ StartTemplate += `<script data-page="true" type="module" data-pathname="${sanitized}" src="${sanitized.endsWith("/") ? sanitized : sanitized + "/"}${name}_data.js" defer="true"></script>`;
260
+ }
261
+ StartTemplate += `<script type="module" src="/client.js" defer="true"></script>`;
262
+ let builtHead;
263
+ if (head2.constructor.name === "AsyncFunction") {
264
+ builtHead = await head2();
265
+ } else {
266
+ builtHead = head2();
267
+ }
268
+ let HTMLTemplate = renderRecursively(builtHead);
269
+ if (serverData) {
270
+ HTMLTemplate += serverData;
271
+ }
272
+ return {
273
+ internals: StartTemplate,
274
+ builtMetadata: HTMLTemplate
275
+ };
276
+ };
277
+ }
278
+ });
279
+
280
+ // src/helpers/ObjectAttributeType.ts
281
+ var init_ObjectAttributeType = __esm({
282
+ "src/helpers/ObjectAttributeType.ts"() {
283
+ "use strict";
284
+ }
285
+ });
286
+
287
+ // src/internal/deprecate.ts
288
+ var init_deprecate = __esm({
289
+ "src/internal/deprecate.ts"() {
290
+ "use strict";
291
+ }
292
+ });
293
+
294
+ // src/server/loadHook.ts
295
+ var resetLoadHooks, getLoadHooks;
296
+ var init_loadHook = __esm({
297
+ "src/server/loadHook.ts"() {
298
+ "use strict";
299
+ init_deprecate();
300
+ resetLoadHooks = () => globalThis.__SERVER_CURRENT_LOADHOOKS__ = [];
301
+ getLoadHooks = () => globalThis.__SERVER_CURRENT_LOADHOOKS__;
302
+ }
303
+ });
304
+
305
+ // src/server/state.ts
306
+ var initializeState, getState, initializeObjectAttributes, getObjectAttributes;
307
+ var init_state = __esm({
308
+ "src/server/state.ts"() {
309
+ "use strict";
310
+ init_ObjectAttributeType();
311
+ init_loadHook();
312
+ if (!globalThis.__SERVER_CURRENT_STATE_ID__) {
313
+ globalThis.__SERVER_CURRENT_STATE_ID__ = 1;
314
+ }
315
+ initializeState = () => globalThis.__SERVER_CURRENT_STATE__ = [];
316
+ getState = () => {
317
+ return globalThis.__SERVER_CURRENT_STATE__;
318
+ };
319
+ initializeObjectAttributes = () => globalThis.__SERVER_CURRENT_OBJECT_ATTRIBUTES__ = [];
320
+ getObjectAttributes = () => {
321
+ return globalThis.__SERVER_CURRENT_OBJECT_ATTRIBUTES__;
322
+ };
323
+ }
324
+ });
325
+
326
+ // src/server/layout.ts
327
+ var resetLayouts;
328
+ var init_layout = __esm({
329
+ "src/server/layout.ts"() {
330
+ "use strict";
331
+ resetLayouts = () => globalThis.__SERVER_CURRENT_LAYOUTS__ = /* @__PURE__ */ new Map();
332
+ if (!globalThis.__SERVER_CURRENT_LAYOUT_ID__) globalThis.__SERVER_CURRENT_LAYOUT_ID__ = 1;
333
+ }
334
+ });
335
+
336
+ // src/page_compiler.ts
337
+ var page_compiler_exports = {};
338
+ __export(page_compiler_exports, {
339
+ buildDynamicPage: () => buildDynamicPage,
340
+ processPageElements: () => processPageElements
341
+ });
2
342
  import fs from "fs";
3
343
  import path from "path";
344
+ import { registerLoader, setArcTsConfig } from "ts-arc";
345
+ import esbuild from "esbuild";
4
346
  import { fileURLToPath } from "url";
347
+ function buildTrace(stack, indent = 4) {
348
+ try {
349
+ if (!stack || stack.length === 0) return "[]";
350
+ let traceObj = stack[stack.length - 1] && typeof stack[stack.length - 1] === "object" ? JSON.parse(JSON.stringify(stack[stack.length - 1])) : { value: stack[stack.length - 1] };
351
+ traceObj._error = "This is the element where the error occurred";
352
+ for (let i = stack.length - 2; i >= 0; i--) {
353
+ const parent = stack[i];
354
+ const child2 = stack[i + 1];
355
+ if (!parent || typeof parent !== "object") {
356
+ traceObj = { value: parent, _errorChild: traceObj };
357
+ continue;
358
+ }
359
+ let parentClone;
360
+ try {
361
+ parentClone = JSON.parse(JSON.stringify(parent));
362
+ } catch {
363
+ parentClone = { value: parent };
364
+ }
365
+ let index = -1;
366
+ if (Array.isArray(parentClone.children)) {
367
+ index = parentClone.children.findIndex((c) => c === child2);
368
+ }
369
+ if (index !== -1 && parentClone.children) {
370
+ parentClone.children = parentClone.children.slice(0, index + 1);
371
+ parentClone.children[index] = traceObj;
372
+ } else {
373
+ parentClone._errorChild = traceObj;
374
+ }
375
+ traceObj = parentClone;
376
+ }
377
+ return JSON.stringify(traceObj, null, indent).replace(/^/gm, " ".repeat(indent));
378
+ } catch {
379
+ return "Could not build stack-trace.";
380
+ }
381
+ }
382
+ var __filename, __dirname, packageDir, clientPath, watcherPath, shippedModules, modulesToShip, yellow, black, bgYellow, bold, underline, white, log2, options, DIST_DIR, PAGE_MAP, LAYOUT_MAP, getAllSubdirectories, buildClient, elementKey, processOptionAsObjectAttribute, processPageElements, pageToHTML, generateClientPageData, generateLayout, builtLayouts, buildLayouts, buildLayout, fetchPageLayoutHTML, buildPages, buildPage, buildDynamicPage, shipModules, build;
383
+ var init_page_compiler = __esm({
384
+ "src/page_compiler.ts"() {
385
+ "use strict";
386
+ init_generateHTMLTemplate();
387
+ init_ObjectAttributeType();
388
+ init_render();
389
+ init_state();
390
+ init_loadHook();
391
+ init_layout();
392
+ init_render();
393
+ __filename = fileURLToPath(import.meta.url);
394
+ __dirname = path.dirname(__filename);
395
+ setArcTsConfig(__dirname);
396
+ registerLoader();
397
+ packageDir = process.env.PACKAGE_PATH;
398
+ if (packageDir === void 0) {
399
+ packageDir = path.resolve(__dirname, "..");
400
+ }
401
+ clientPath = path.resolve(packageDir, "./dist/client/client.mjs");
402
+ watcherPath = path.resolve(packageDir, "./dist/client/watcher.mjs");
403
+ shippedModules = /* @__PURE__ */ new Map();
404
+ modulesToShip = [];
405
+ yellow = (text) => {
406
+ return `\x1B[38;2;238;184;68m${text}`;
407
+ };
408
+ black = (text) => {
409
+ return `\x1B[38;2;0;0;0m${text}`;
410
+ };
411
+ bgYellow = (text) => {
412
+ return `\x1B[48;2;238;184;68m${text}`;
413
+ };
414
+ bold = (text) => {
415
+ return `\x1B[1m${text}`;
416
+ };
417
+ underline = (text) => {
418
+ return `\x1B[4m${text}`;
419
+ };
420
+ white = (text) => {
421
+ return `\x1B[38;2;255;247;229m${text}`;
422
+ };
423
+ log2 = (...text) => {
424
+ if (options.quiet) return;
425
+ return console.log(text.map((text2) => `${text2}\x1B[0m`).join(""));
426
+ };
427
+ options = JSON.parse(process.env.OPTIONS || "{}");
428
+ console.log(options);
429
+ DIST_DIR = process.env.DIST_DIR;
430
+ PAGE_MAP = /* @__PURE__ */ new Map();
431
+ LAYOUT_MAP = /* @__PURE__ */ new Map();
432
+ getAllSubdirectories = (dir, baseDir = dir) => {
433
+ let directories = [];
434
+ const items = fs.readdirSync(dir, { withFileTypes: true });
435
+ for (const item of items) {
436
+ if (item.isDirectory()) {
437
+ const fullPath = path.join(dir, item.name);
438
+ const relativePath = path.relative(baseDir, fullPath);
439
+ directories.push(relativePath);
440
+ directories = directories.concat(getAllSubdirectories(fullPath, baseDir));
441
+ }
442
+ }
443
+ return directories;
444
+ };
445
+ buildClient = async (DIST_DIR2) => {
446
+ let clientString = "window.__name = (func) => func; ";
447
+ clientString += fs.readFileSync(clientPath, "utf-8");
448
+ if (options.hotReload !== void 0) {
449
+ clientString += `const watchServerPort = ${options.hotReload.port}`;
450
+ clientString += fs.readFileSync(watcherPath, "utf-8");
451
+ }
452
+ const transformedClient = await esbuild.transform(clientString, {
453
+ minify: options.environment === "production",
454
+ drop: options.environment === "production" ? ["console", "debugger"] : void 0,
455
+ keepNames: false,
456
+ format: "iife",
457
+ platform: "node",
458
+ loader: "ts"
459
+ });
460
+ fs.writeFileSync(
461
+ path.join(DIST_DIR2, "/client.js"),
462
+ transformedClient.code
463
+ );
464
+ };
465
+ elementKey = 0;
466
+ processOptionAsObjectAttribute = (element, optionName, optionValue, objectAttributes) => {
467
+ const lcOptionName = optionName.toLowerCase();
468
+ const options3 = element.options;
469
+ let key = options3.key;
470
+ if (key == void 0) {
471
+ key = elementKey += 1;
472
+ options3.key = key;
473
+ }
474
+ if (!optionValue.type) {
475
+ throw `ObjectAttributeType is missing from object attribute. ${element.tag}: ${optionName}/${optionValue}`;
476
+ }
477
+ let optionFinal = lcOptionName;
478
+ switch (optionValue.type) {
479
+ case 1 /* STATE */:
480
+ const SOA = optionValue;
481
+ if (typeof SOA.value === "function") {
482
+ delete options3[optionName];
483
+ break;
484
+ }
485
+ if (lcOptionName === "innertext" || lcOptionName === "innerhtml") {
486
+ element.children = [SOA.value];
487
+ delete options3[optionName];
488
+ } else {
489
+ delete options3[optionName];
490
+ options3[lcOptionName] = SOA.value;
491
+ }
492
+ break;
493
+ case 2 /* OBSERVER */:
494
+ const OOA = optionValue;
495
+ const firstValue = OOA.update(...OOA.initialValues);
496
+ if (lcOptionName === "innertext" || lcOptionName === "innerhtml") {
497
+ element.children = [firstValue];
498
+ delete options3[optionName];
499
+ } else {
500
+ delete options3[optionName];
501
+ options3[lcOptionName] = firstValue;
502
+ }
503
+ optionFinal = optionName;
504
+ break;
505
+ case 4 /* REFERENCE */:
506
+ options3["ref"] = optionValue.value;
507
+ break;
508
+ }
509
+ objectAttributes.push({ ...optionValue, key, attribute: optionFinal });
510
+ };
511
+ processPageElements = (element, objectAttributes, recursionLevel, stack = []) => {
512
+ stack.push(element);
513
+ try {
514
+ if (typeof element === "boolean" || typeof element === "number" || Array.isArray(element)) {
515
+ stack.pop();
516
+ return element;
517
+ }
518
+ if (typeof element === "string") {
519
+ stack.pop();
520
+ return element;
521
+ }
522
+ const processElementOptionsAsChildAndReturn = () => {
523
+ try {
524
+ const children = element.children;
525
+ element.children = [
526
+ element.options,
527
+ ...children
528
+ ];
529
+ element.options = {};
530
+ for (let i = 0; i < children.length + 1; i++) {
531
+ const child2 = element.children[i];
532
+ const processedChild = processPageElements(child2, objectAttributes, recursionLevel + 1, stack);
533
+ element.children[i] = processedChild;
534
+ }
535
+ return {
536
+ ...element,
537
+ options: {}
538
+ };
539
+ } catch (e) {
540
+ const errorString = `Could not process element options as a child. ${e}.`;
541
+ throw new Error(errorString);
542
+ }
543
+ };
544
+ if (typeof element.options !== "object") {
545
+ const result = processElementOptionsAsChildAndReturn();
546
+ stack.pop();
547
+ return result;
548
+ }
549
+ const {
550
+ tag: elementTag,
551
+ options: elementOptions,
552
+ children: elementChildren
553
+ } = element.options;
554
+ if (elementTag && elementOptions && elementChildren) {
555
+ const result = processElementOptionsAsChildAndReturn();
556
+ stack.pop();
557
+ return result;
558
+ }
559
+ const options3 = element.options;
560
+ for (const [optionName, optionValue] of Object.entries(options3)) {
561
+ const lcOptionName = optionName.toLowerCase();
562
+ if (typeof optionValue !== "object") {
563
+ if (lcOptionName === "innertext") {
564
+ delete options3[optionName];
565
+ if (element.children === null) {
566
+ throw `Cannot use innerText or innerHTML on childrenless elements.`;
567
+ }
568
+ element.children = [optionValue, ...element.children];
569
+ continue;
570
+ } else if (lcOptionName === "innerhtml") {
571
+ if (element.children === null) {
572
+ throw `Cannot use innerText or innerHTML on childrenless elements.`;
573
+ }
574
+ delete options3[optionName];
575
+ element.children = [optionValue];
576
+ continue;
577
+ }
578
+ continue;
579
+ }
580
+ ;
581
+ processOptionAsObjectAttribute(element, optionName, optionValue, objectAttributes);
582
+ }
583
+ if (element.children) {
584
+ for (let i = 0; i < element.children.length; i++) {
585
+ const child2 = element.children[i];
586
+ const processedChild = processPageElements(child2, objectAttributes, recursionLevel + 1, stack);
587
+ element.children[i] = processedChild;
588
+ }
589
+ }
590
+ stack.pop();
591
+ return element;
592
+ } catch (e) {
593
+ const trace = buildTrace(stack);
594
+ if (recursionLevel === 0) {
595
+ throw new Error(`${e}
596
+
597
+ Trace:
598
+ ${trace}`);
599
+ } else {
600
+ throw e;
601
+ }
602
+ }
603
+ };
604
+ pageToHTML = async (pageLocation, pageElements, metadata, DIST_DIR2, pageName, doWrite = true, requiredClientModules = {}, layout, pathname = "") => {
605
+ if (typeof pageElements === "string" || typeof pageElements === "boolean" || typeof pageElements === "number" || Array.isArray(pageElements)) {
606
+ throw new Error(`The root element of a page / layout must be a built element, not just a Child. Received: ${typeof pageElements}.`);
607
+ }
608
+ const objectAttributes = [];
609
+ const stack = [];
610
+ const processedPageElements = processPageElements(pageElements, objectAttributes, 0, stack);
611
+ const renderedPage = await serverSideRenderPage(
612
+ processedPageElements,
613
+ pageLocation
614
+ );
615
+ const { internals, builtMetadata } = await generateHTMLTemplate({
616
+ pageURL: pathname,
617
+ head: metadata,
618
+ addPageScriptTag: doWrite,
619
+ name: pageName,
620
+ requiredClientModules,
621
+ environment: options.environment
622
+ });
623
+ let extraBodyHTML = "";
624
+ if (doWrite === false) {
625
+ const state = getState();
626
+ const pageLoadHooks = getLoadHooks();
627
+ const userObjectAttributes = getObjectAttributes();
628
+ const {
629
+ result
630
+ } = await generateClientPageData(
631
+ pathname,
632
+ state || {},
633
+ [...objectAttributes, ...userObjectAttributes],
634
+ pageLoadHooks || [],
635
+ DIST_DIR2,
636
+ "page",
637
+ "pd",
638
+ false
639
+ );
640
+ const sanitized = pathname === "" ? "/" : `/${pathname}`;
641
+ extraBodyHTML = `<script data-hook="true" data-pathname="${sanitized}" type="text/plain">${result}</script>`;
642
+ extraBodyHTML += `<script>
643
+ const text = document.querySelector('[data-hook="true"][data-pathname="${sanitized}"][type="text/plain"').textContent;
644
+ const blob = new Blob([text], { type: 'text/javascript' });
645
+ const url = URL.createObjectURL(blob);
646
+
647
+ const script = document.createElement("script");
648
+ script.src = url;
649
+ script.type = "module";
650
+ script.setAttribute("data-page", "true");
651
+ script.setAttribute("data-pathname", "${sanitized}");
652
+
653
+ document.head.appendChild(script);
654
+
655
+ document.currentScript.remove();
656
+ </script>`;
657
+ extraBodyHTML = extraBodyHTML.replace(/\s+/g, " ").replace(/\s*([{}();,:])\s*/g, "$1").trim();
658
+ }
659
+ const headHTML = `<!DOCTYPE html>${layout.metadata.startHTML}${layout.scriptTag}${internals}${builtMetadata}${layout.metadata.endHTML}`;
660
+ const bodyHTML = `${layout.pageContent.startHTML}${renderedPage.bodyHTML}${extraBodyHTML}${layout.pageContent.endHTML}`;
661
+ const resultHTML = `${headHTML}${bodyHTML}`;
662
+ const htmlLocation = path.join(pageLocation, (pageName === "page" ? "index" : pageName) + ".html");
663
+ if (doWrite) {
664
+ const dirname2 = path.dirname(htmlLocation);
665
+ if (fs.existsSync(dirname2) === false) {
666
+ fs.mkdirSync(dirname2, { recursive: true });
667
+ }
668
+ fs.writeFileSync(
669
+ htmlLocation,
670
+ resultHTML,
671
+ {
672
+ encoding: "utf-8",
673
+ flag: "w"
674
+ }
675
+ );
676
+ return objectAttributes;
677
+ }
678
+ return resultHTML;
679
+ };
680
+ generateClientPageData = async (pageLocation, state, objectAttributes, pageLoadHooks, DIST_DIR2, pageName, globalVariableName = "pd", write = true) => {
681
+ let clientPageJSText = "";
682
+ {
683
+ clientPageJSText += `${globalThis.__SERVER_PAGE_DATA_BANNER__}`;
684
+ }
685
+ {
686
+ clientPageJSText += `export const data = {`;
687
+ if (state) {
688
+ clientPageJSText += `state:[`;
689
+ for (const subject of state) {
690
+ if (typeof subject.value === "string") {
691
+ const stringified = JSON.stringify(subject.value);
692
+ clientPageJSText += `{id:${subject.id},value:${stringified}},`;
693
+ } else if (typeof subject.value === "function") {
694
+ clientPageJSText += `{id:${subject.id},value:${subject.value.toString()}},`;
695
+ } else {
696
+ clientPageJSText += `{id:${subject.id},value:${JSON.stringify(subject.value)}},`;
697
+ }
698
+ }
699
+ clientPageJSText += `],`;
700
+ }
701
+ const stateObjectAttributes = objectAttributes.filter((oa) => oa.type === 1 /* STATE */);
702
+ if (stateObjectAttributes.length > 0) {
703
+ const processed = [...stateObjectAttributes].map((soa) => {
704
+ delete soa.type;
705
+ return soa;
706
+ });
707
+ clientPageJSText += `soa:${JSON.stringify(processed)},`;
708
+ }
709
+ const observerObjectAttributes = objectAttributes.filter((oa) => oa.type === 2 /* OBSERVER */);
710
+ if (observerObjectAttributes.length > 0) {
711
+ let observerObjectAttributeString = "ooa:[";
712
+ for (const observerObjectAttribute of observerObjectAttributes) {
713
+ const ooa = observerObjectAttribute;
714
+ observerObjectAttributeString += `{key:${ooa.key},attribute:"${ooa.attribute}",update:${ooa.update.toString()},`;
715
+ observerObjectAttributeString += `refs:[`;
716
+ for (const ref of ooa.refs) {
717
+ observerObjectAttributeString += `{id:${ref.id}},`;
718
+ }
719
+ observerObjectAttributeString += "]},";
720
+ }
721
+ observerObjectAttributeString += "],";
722
+ clientPageJSText += observerObjectAttributeString;
723
+ }
724
+ if (pageLoadHooks.length > 0) {
725
+ clientPageJSText += "lh:[";
726
+ for (const loadHook2 of pageLoadHooks) {
727
+ clientPageJSText += `{fn:${loadHook2.fn}},`;
728
+ }
729
+ clientPageJSText += "],";
730
+ }
731
+ clientPageJSText += `};`;
732
+ }
733
+ const pageDataPath = path.join(DIST_DIR2, pageLocation, `${pageName}_data.js`);
734
+ let sendHardReloadInstruction = false;
735
+ const transformedResult = await esbuild.transform(clientPageJSText, { minify: options.environment === "production" }).catch((error) => {
736
+ console.error("Failed to transform client page js!", error);
737
+ });
738
+ if (!transformedResult) return { sendHardReloadInstruction };
739
+ if (fs.existsSync(pageDataPath)) {
740
+ const content = fs.readFileSync(pageDataPath).toString();
741
+ if (content !== transformedResult.code) {
742
+ sendHardReloadInstruction = true;
743
+ }
744
+ }
745
+ if (write) fs.writeFileSync(pageDataPath, transformedResult.code, "utf-8");
746
+ return { sendHardReloadInstruction, result: transformedResult.code };
747
+ };
748
+ generateLayout = async (DIST_DIR2, filePath, directory, childIndicator, generateDynamic = false) => {
749
+ initializeState();
750
+ initializeObjectAttributes();
751
+ resetLoadHooks();
752
+ globalThis.__SERVER_PAGE_DATA_BANNER__ = "";
753
+ let layoutElements;
754
+ let metadataElements;
755
+ let modules = [];
756
+ let isDynamicLayout = false;
757
+ try {
758
+ const {
759
+ layout,
760
+ metadata,
761
+ isDynamic,
762
+ shippedModules: shippedModules2
763
+ } = await import("file://" + filePath);
764
+ if (shippedModules2 !== void 0) {
765
+ modules = shippedModules2;
766
+ }
767
+ layoutElements = layout;
768
+ metadataElements = metadata;
769
+ if (isDynamic === true) {
770
+ isDynamicLayout = isDynamic;
771
+ }
772
+ } catch (e) {
773
+ throw new Error(`Error in Page: ${directory === "" ? "/" : directory}layout.ts - ${e}`);
774
+ }
775
+ LAYOUT_MAP.set(directory === "" ? "/" : `/${directory}`, {
776
+ isDynamic: isDynamicLayout,
777
+ filePath
778
+ });
779
+ if (isDynamicLayout === true && generateDynamic === false) return false;
780
+ {
781
+ if (!layoutElements) {
782
+ throw new Error(`WARNING: ${filePath} should export a const layout, which is of type Layout: (child: Child) => AnyBuiltElement.`);
783
+ }
784
+ if (typeof layoutElements === "function") {
785
+ if (layoutElements.constructor.name === "AsyncFunction") {
786
+ layoutElements = await layoutElements(childIndicator);
787
+ } else {
788
+ layoutElements = layoutElements(childIndicator);
789
+ }
790
+ }
791
+ }
792
+ {
793
+ if (!metadataElements) {
794
+ throw new Error(`WARNING: ${filePath} should export a const metadata, which is of type LayoutMetadata: (child: Child) => AnyBuiltElement.`);
795
+ }
796
+ if (typeof metadataElements === "function") {
797
+ if (metadataElements.constructor.name === "AsyncFunction") {
798
+ metadataElements = await metadataElements(childIndicator);
799
+ } else {
800
+ metadataElements = metadataElements(childIndicator);
801
+ }
802
+ }
803
+ }
804
+ const state = getState();
805
+ const pageLoadHooks = getLoadHooks();
806
+ const objectAttributes = getObjectAttributes();
807
+ if (typeof layoutElements === "string" || typeof layoutElements === "boolean" || typeof layoutElements === "number" || Array.isArray(layoutElements)) {
808
+ throw new Error(`The root element of a page / layout must be a built element, not just a Child. Received: ${typeof layoutElements}.`);
809
+ }
810
+ const foundObjectAttributes = [];
811
+ const stack = [];
812
+ const processedPageElements = processPageElements(layoutElements, foundObjectAttributes, 0, stack);
813
+ const renderedPage = await serverSideRenderPage(
814
+ processedPageElements,
815
+ directory
816
+ );
817
+ const metadataHTML = metadataElements ? renderRecursively(metadataElements) : "";
818
+ await generateClientPageData(
819
+ directory,
820
+ state || {},
821
+ [...objectAttributes, ...foundObjectAttributes],
822
+ pageLoadHooks || [],
823
+ DIST_DIR2,
824
+ "layout",
825
+ "ld"
826
+ );
827
+ return { pageContentHTML: renderedPage.bodyHTML, metadataHTML };
828
+ };
829
+ builtLayouts = /* @__PURE__ */ new Map();
830
+ buildLayouts = async () => {
831
+ const pagesDirectory = path.resolve(options.pagesDirectory);
832
+ const subdirectories = [...getAllSubdirectories(pagesDirectory), ""];
833
+ let shouldClientHardReload = false;
834
+ for (const directory of subdirectories) {
835
+ const abs = path.resolve(path.join(pagesDirectory, directory));
836
+ const files = fs.readdirSync(abs, { withFileTypes: true }).filter((f) => f.name.endsWith(".ts"));
837
+ for (const file of files) {
838
+ const filePath = path.join(file.parentPath, file.name);
839
+ const name = file.name.slice(0, file.name.length - 3);
840
+ const isLayout = name === "layout";
841
+ if (isLayout == false) {
842
+ continue;
843
+ }
844
+ try {
845
+ const builtLayout = await buildLayout(filePath, directory);
846
+ if (!builtLayout) return { shouldClientHardReload: false };
847
+ builtLayouts.set(filePath, builtLayout);
848
+ } catch (e) {
849
+ console.error(e);
850
+ continue;
851
+ }
852
+ }
853
+ }
854
+ return { shouldClientHardReload };
855
+ };
856
+ buildLayout = async (filePath, directory, generateDynamic = false) => {
857
+ const id = globalThis.__SERVER_CURRENT_STATE_ID__ += 1;
858
+ const childIndicator = `<template layout-id="${id}"></template>`;
859
+ const result = await generateLayout(
860
+ DIST_DIR,
861
+ filePath,
862
+ directory,
863
+ childIndicator,
864
+ generateDynamic
865
+ );
866
+ if (result === false) return false;
867
+ const { pageContentHTML, metadataHTML } = result;
868
+ const splitAround = (str, sub) => {
869
+ const i = str.indexOf(sub);
870
+ if (i === -1) throw new Error("substring does not exist in parent string");
871
+ return {
872
+ startHTML: str.substring(0, i),
873
+ endHTML: str.substring(i + sub.length)
874
+ };
875
+ };
876
+ const splitAt = (str, sub) => {
877
+ const i = str.indexOf(sub) + sub.length;
878
+ if (i === -1) throw new Error("substring does not exist in parent string");
879
+ return {
880
+ startHTML: str.substring(0, i),
881
+ endHTML: str.substring(i)
882
+ };
883
+ };
884
+ const pathname = directory === "" ? "/" : directory;
885
+ return {
886
+ pageContent: splitAt(pageContentHTML, childIndicator),
887
+ metadata: splitAround(metadataHTML, childIndicator),
888
+ scriptTag: `<script data-layout="true" type="module" src="${pathname}layout_data.js" data-pathname="${pathname}" defer="true"></script>`
889
+ };
890
+ };
891
+ fetchPageLayoutHTML = async (dirname2) => {
892
+ const relative2 = path.relative(options.pagesDirectory, dirname2);
893
+ let split = relative2.split(path.sep).filter(Boolean);
894
+ split.push("/");
895
+ split.reverse();
896
+ let layouts = [];
897
+ for (const dir of split) {
898
+ if (LAYOUT_MAP.has(dir)) {
899
+ const filePath = path.join(path.resolve(options.pagesDirectory), dir, "layout.ts");
900
+ const layout = LAYOUT_MAP.get(dir);
901
+ if (layout.isDynamic) {
902
+ const builtLayout = await buildLayout(layout.filePath, dir, true);
903
+ if (!builtLayout) continue;
904
+ layouts.push(builtLayout);
905
+ } else {
906
+ layouts.push(builtLayouts.get(filePath));
907
+ }
908
+ }
909
+ }
910
+ const pageContent = {
911
+ startHTML: "",
912
+ endHTML: ""
913
+ };
914
+ const metadata = {
915
+ startHTML: "",
916
+ endHTML: ""
917
+ };
918
+ let scriptTags = "";
919
+ for (const layout of layouts) {
920
+ pageContent.startHTML += layout.pageContent.startHTML;
921
+ metadata.startHTML += layout.metadata.startHTML;
922
+ scriptTags += layout.scriptTag;
923
+ pageContent.endHTML += layout.pageContent.endHTML;
924
+ metadata.endHTML += layout.metadata.endHTML;
925
+ }
926
+ return { pageContent, metadata, scriptTag: scriptTags };
927
+ };
928
+ buildPages = async (DIST_DIR2) => {
929
+ resetLayouts();
930
+ const pagesDirectory = path.resolve(options.pagesDirectory);
931
+ const subdirectories = [...getAllSubdirectories(pagesDirectory), ""];
932
+ let shouldClientHardReload = false;
933
+ for (const directory of subdirectories) {
934
+ const abs = path.resolve(path.join(pagesDirectory, directory));
935
+ const files = fs.readdirSync(abs, { withFileTypes: true }).filter((f) => f.name.endsWith(".ts"));
936
+ for (const file of files) {
937
+ const filePath = path.join(file.parentPath, file.name);
938
+ const name = file.name.slice(0, file.name.length - 3);
939
+ const isPage = name === "page";
940
+ if (isPage == false) {
941
+ continue;
942
+ }
943
+ try {
944
+ const hardReloadForPage = await buildPage(DIST_DIR2, directory, filePath, name);
945
+ if (hardReloadForPage) {
946
+ shouldClientHardReload = true;
947
+ }
948
+ } catch (e) {
949
+ console.error(e);
950
+ continue;
951
+ }
952
+ }
953
+ }
954
+ return {
955
+ shouldClientHardReload
956
+ };
957
+ };
958
+ buildPage = async (DIST_DIR2, directory, filePath, name) => {
959
+ initializeState();
960
+ initializeObjectAttributes();
961
+ resetLoadHooks();
962
+ globalThis.__SERVER_PAGE_DATA_BANNER__ = "";
963
+ let pageElements;
964
+ let metadata;
965
+ let modules = {};
966
+ let pageIgnoresLayout = false;
967
+ let isDynamicPage = false;
968
+ try {
969
+ const {
970
+ page,
971
+ metadata: pageMetadata,
972
+ isDynamic,
973
+ shippedModules: shippedModules2,
974
+ ignoreLayout
975
+ } = await import("file://" + filePath);
976
+ if (shippedModules2 !== void 0) {
977
+ modules = shippedModules2;
978
+ }
979
+ if (ignoreLayout) {
980
+ pageIgnoresLayout = true;
981
+ }
982
+ pageElements = page;
983
+ metadata = pageMetadata;
984
+ if (isDynamic === true) {
985
+ isDynamicPage = isDynamic;
986
+ }
987
+ } catch (e) {
988
+ throw new Error(`Error in Page: ${directory}/${name}.ts - ${e}`);
989
+ }
990
+ PAGE_MAP.set(directory === "" ? "/" : `/${directory}`, {
991
+ isDynamic: isDynamicPage,
992
+ filePath
993
+ });
994
+ if (isDynamicPage) return false;
995
+ if (modules !== void 0) {
996
+ for (const [globalName, path3] of Object.entries(modules)) {
997
+ modulesToShip.push({ globalName, path: path3 });
998
+ }
999
+ }
1000
+ if (!metadata || metadata && typeof metadata !== "function") {
1001
+ console.warn(`WARNING: ${filePath} does not export a metadata function.`);
1002
+ }
1003
+ if (!pageElements) {
1004
+ console.warn(`WARNING: ${filePath} should export a const page, which is of type () => BuiltElement<"body">.`);
1005
+ }
1006
+ const pageProps = {
1007
+ pageName: directory,
1008
+ middlewareData: {}
1009
+ };
1010
+ if (typeof pageElements === "function") {
1011
+ if (pageElements.constructor.name === "AsyncFunction") {
1012
+ pageElements = await pageElements(pageProps);
1013
+ } else {
1014
+ pageElements = pageElements(pageProps);
1015
+ }
1016
+ }
1017
+ const state = getState();
1018
+ const pageLoadHooks = getLoadHooks();
1019
+ const objectAttributes = getObjectAttributes();
1020
+ const layout = await fetchPageLayoutHTML(path.dirname(filePath));
1021
+ const foundObjectAttributes = await pageToHTML(
1022
+ path.join(DIST_DIR2, directory),
1023
+ pageElements || body(),
1024
+ metadata ?? (() => head()),
1025
+ DIST_DIR2,
1026
+ name,
1027
+ true,
1028
+ modules,
1029
+ layout,
1030
+ directory
1031
+ );
1032
+ const {
1033
+ sendHardReloadInstruction
1034
+ } = await generateClientPageData(
1035
+ directory,
1036
+ state || {},
1037
+ [...objectAttributes, ...foundObjectAttributes],
1038
+ pageLoadHooks || [],
1039
+ DIST_DIR2,
1040
+ name
1041
+ );
1042
+ return sendHardReloadInstruction === true;
1043
+ };
1044
+ buildDynamicPage = async (DIST_DIR2, directory, pageInfo, req, res, middlewareData) => {
1045
+ directory = directory === "/" ? "" : directory;
1046
+ const filePath = pageInfo.filePath;
1047
+ initializeState();
1048
+ initializeObjectAttributes();
1049
+ resetLoadHooks();
1050
+ globalThis.__SERVER_PAGE_DATA_BANNER__ = "";
1051
+ let pageElements = async (props) => body();
1052
+ let metadata = async (props) => html();
1053
+ let modules = {};
1054
+ let pageIgnoresLayout = false;
1055
+ try {
1056
+ const {
1057
+ page,
1058
+ metadata: pageMetadata,
1059
+ shippedModules: shippedModules2,
1060
+ ignoreLayout,
1061
+ requestHook
1062
+ } = await import("file://" + filePath);
1063
+ if (requestHook) {
1064
+ const hook = requestHook;
1065
+ const doContinue = await hook(req, res);
1066
+ if (!doContinue) {
1067
+ return false;
1068
+ }
1069
+ }
1070
+ if (shippedModules2 !== void 0) {
1071
+ modules = shippedModules2;
1072
+ }
1073
+ if (ignoreLayout) {
1074
+ pageIgnoresLayout = true;
1075
+ }
1076
+ pageElements = page;
1077
+ metadata = pageMetadata;
1078
+ } catch (e) {
1079
+ throw new Error(`Error in Page: ${directory}/page.ts - ${e}`);
1080
+ }
1081
+ if (modules !== void 0) {
1082
+ for (const [globalName, path3] of Object.entries(modules)) {
1083
+ modulesToShip.push({ globalName, path: path3 });
1084
+ }
1085
+ }
1086
+ if (!metadata || metadata && typeof metadata !== "function") {
1087
+ console.warn(`WARNING: ${filePath} does not export a metadata function.`);
1088
+ }
1089
+ if (!pageElements) {
1090
+ console.warn(`WARNING: ${filePath} should export a const page, which is of type () => BuiltElement<"body">.`);
1091
+ }
1092
+ const pageProps = {
1093
+ pageName: directory,
1094
+ middlewareData
1095
+ };
1096
+ if (typeof pageElements === "function") {
1097
+ if (pageElements.constructor.name === "AsyncFunction") {
1098
+ pageElements = await pageElements(pageProps);
1099
+ } else {
1100
+ pageElements = pageElements(pageProps);
1101
+ }
1102
+ }
1103
+ const layout = await fetchPageLayoutHTML(path.dirname(filePath));
1104
+ const resultHTML = await pageToHTML(
1105
+ path.join(DIST_DIR2, directory),
1106
+ pageElements,
1107
+ metadata,
1108
+ DIST_DIR2,
1109
+ "page",
1110
+ false,
1111
+ modules,
1112
+ layout,
1113
+ directory
1114
+ );
1115
+ await shipModules();
1116
+ return { resultHTML };
1117
+ };
1118
+ shipModules = async () => {
1119
+ for (const plugin of modulesToShip) {
1120
+ {
1121
+ if (shippedModules.has(plugin.globalName)) continue;
1122
+ shippedModules.set(plugin.globalName, true);
1123
+ }
1124
+ esbuild.build({
1125
+ entryPoints: [plugin.path],
1126
+ bundle: true,
1127
+ outfile: path.join(DIST_DIR, "shipped", plugin.globalName + ".js"),
1128
+ format: "iife",
1129
+ platform: "browser",
1130
+ globalName: plugin.globalName,
1131
+ minify: true,
1132
+ treeShaking: true
1133
+ });
1134
+ }
1135
+ modulesToShip = [];
1136
+ };
1137
+ build = async () => {
1138
+ if (options.quiet === true) {
1139
+ console.log = function() {
1140
+ };
1141
+ console.error = function() {
1142
+ };
1143
+ console.warn = function() {
1144
+ };
1145
+ }
1146
+ try {
1147
+ {
1148
+ log2(bold(yellow(" -- Elegance.JS -- ")));
1149
+ if (options.environment === "production") {
1150
+ log2(
1151
+ " - ",
1152
+ bgYellow(bold(black(" NOTE "))),
1153
+ " : ",
1154
+ white("In production mode, no "),
1155
+ underline("console.log() "),
1156
+ white("statements will be shown on the client, and all code will be minified.")
1157
+ );
1158
+ log2("");
1159
+ }
1160
+ }
1161
+ if (options.preCompile) {
1162
+ options.preCompile();
1163
+ }
1164
+ const start = performance.now();
1165
+ let shouldClientHardReload;
1166
+ {
1167
+ const { shouldClientHardReload: doReload } = await buildLayouts();
1168
+ if (doReload) shouldClientHardReload = true;
1169
+ }
1170
+ {
1171
+ const { shouldClientHardReload: doReload } = await buildPages(path.resolve(DIST_DIR));
1172
+ if (doReload) shouldClientHardReload = true;
1173
+ }
1174
+ await shipModules();
1175
+ const pagesBuilt = performance.now();
1176
+ await buildClient(DIST_DIR);
1177
+ const end = performance.now();
1178
+ if (options.publicDirectory) {
1179
+ log2("Recursively copying public directory.. this may take a while.");
1180
+ const src = path.relative(process.cwd(), options.publicDirectory.path);
1181
+ if (fs.existsSync(src) === false) {
1182
+ console.warn("WARNING: Public directory not found, an attempt will be made create it..");
1183
+ fs.mkdirSync(src, { recursive: true });
1184
+ }
1185
+ await fs.promises.cp(src, path.join(DIST_DIR), { recursive: true });
1186
+ }
1187
+ {
1188
+ log2(`Took ${Math.round(pagesBuilt - start)}ms to Build Pages.`);
1189
+ log2(`Took ${Math.round(end - pagesBuilt)}ms to Build Client.`);
1190
+ }
1191
+ process.send?.({ event: "message", data: "set-pages-and-layouts", content: JSON.stringify({ pageMap: Array.from(PAGE_MAP), layoutMap: Array.from(LAYOUT_MAP) }) });
1192
+ process.send?.({ event: "message", data: "compile-finish" });
1193
+ if (shouldClientHardReload) {
1194
+ process.send({ event: "message", data: "hard-reload" });
1195
+ } else {
1196
+ process.send({ event: "message", data: "soft-reload" });
1197
+ }
1198
+ } catch (e) {
1199
+ console.error("Build Failed! Received Error:");
1200
+ console.error(e);
1201
+ return false;
1202
+ }
1203
+ return true;
1204
+ };
1205
+ (async () => {
1206
+ if (process.env.DO_BUILD === "true") await build();
1207
+ })();
1208
+ }
1209
+ });
1210
+
1211
+ // src/build.ts
1212
+ import fs3 from "fs";
1213
+ import path2 from "path";
1214
+ import { fileURLToPath as fileURLToPath3 } from "url";
5
1215
  import child_process from "node:child_process";
6
1216
  import http from "http";
7
1217
 
1218
+ // src/server/server.ts
1219
+ import {
1220
+ createServer as createHttpServer
1221
+ } from "http";
1222
+ import {
1223
+ promises as fs2
1224
+ } from "fs";
1225
+ import {
1226
+ join,
1227
+ normalize,
1228
+ extname,
1229
+ dirname
1230
+ } from "path";
1231
+ import {
1232
+ pathToFileURL
1233
+ } from "url";
1234
+
8
1235
  // src/log.ts
9
1236
  var quiet = false;
10
1237
  function setQuiet(value) {
@@ -41,18 +1268,445 @@ var log = {
41
1268
  error: logError
42
1269
  };
43
1270
 
1271
+ // src/server/server.ts
1272
+ import {
1273
+ gzip,
1274
+ deflate
1275
+ } from "zlib";
1276
+ import {
1277
+ promisify
1278
+ } from "util";
1279
+ var gzipAsync = promisify(gzip);
1280
+ var deflateAsync = promisify(deflate);
1281
+ var MIME_TYPES = {
1282
+ ".html": "text/html; charset=utf-8",
1283
+ ".css": "text/css; charset=utf-8",
1284
+ ".js": "application/javascript; charset=utf-8",
1285
+ ".json": "application/json; charset=utf-8",
1286
+ ".png": "image/png",
1287
+ ".jpg": "image/jpeg",
1288
+ ".jpeg": "image/jpeg",
1289
+ ".gif": "image/gif",
1290
+ ".svg": "image/svg+xml",
1291
+ ".ico": "image/x-icon",
1292
+ ".txt": "text/plain; charset=utf-8"
1293
+ };
1294
+ function startServer({
1295
+ root,
1296
+ pagesDirectory,
1297
+ port = 3e3,
1298
+ host = "localhost",
1299
+ environment = "production",
1300
+ DIST_DIR: DIST_DIR2
1301
+ }) {
1302
+ if (!root) throw new Error("Root directory must be specified.");
1303
+ if (!pagesDirectory) throw new Error("Pages directory must be specified.");
1304
+ root = normalize(root).replace(/[\\/]+$/, "");
1305
+ pagesDirectory = normalize(pagesDirectory).replace(/[\\/]+$/, "");
1306
+ const requestHandler = async (req, res) => {
1307
+ try {
1308
+ if (!req.url) {
1309
+ await sendResponse(req, res, 400, {
1310
+ "Content-Type": "text/plain; charset=utf-8"
1311
+ }, "Bad Request");
1312
+ return;
1313
+ }
1314
+ res.setHeader("Access-Control-Allow-Origin", "*");
1315
+ res.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
1316
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
1317
+ if (req.method === "OPTIONS") {
1318
+ res.writeHead(204);
1319
+ res.end();
1320
+ if (environment === "development") {
1321
+ log.info(req.method, "::", req.url, "-", res.statusCode);
1322
+ }
1323
+ return;
1324
+ }
1325
+ const url = new URL(req.url, `http://${req.headers.host}`);
1326
+ if (url.pathname.startsWith("/api/")) {
1327
+ await handleApiRequest(pagesDirectory, url.pathname, req, res);
1328
+ } else if (PAGE_MAP2.has(url.pathname)) {
1329
+ await handlePageRequest(root, pagesDirectory, url.pathname, req, res, DIST_DIR2, PAGE_MAP2.get(url.pathname));
1330
+ } else {
1331
+ await handleStaticRequest(root, pagesDirectory, url.pathname, req, res, DIST_DIR2);
1332
+ }
1333
+ if (environment === "development") {
1334
+ log.info(req.method, "::", req.url, "-", res.statusCode);
1335
+ }
1336
+ } catch (err) {
1337
+ log.error(err);
1338
+ await sendResponse(req, res, 500, {
1339
+ "Content-Type": "text/plain; charset=utf-8"
1340
+ }, "Internal Server Error");
1341
+ }
1342
+ };
1343
+ function attemptListen(p) {
1344
+ const server = createHttpServer(requestHandler);
1345
+ server.on("error", (err) => {
1346
+ if (err.code === "EADDRINUSE") {
1347
+ attemptListen(p + 1);
1348
+ } else {
1349
+ console.error(err);
1350
+ }
1351
+ });
1352
+ server.listen(p, host, () => {
1353
+ log.info(`Server running at http://${host}:${p}/`);
1354
+ });
1355
+ return server;
1356
+ }
1357
+ return attemptListen(port);
1358
+ }
1359
+ async function getTargetInfo(root, pathname) {
1360
+ const originalPathname = pathname;
1361
+ const filePath = normalize(join(root, decodeURIComponent(pathname))).replace(/[\\/]+$/, "");
1362
+ if (!filePath.startsWith(root)) {
1363
+ throw new Error("Forbidden");
1364
+ }
1365
+ let stats;
1366
+ try {
1367
+ stats = await fs2.stat(filePath);
1368
+ } catch {
1369
+ }
1370
+ let targetDir;
1371
+ if (stats) {
1372
+ targetDir = stats.isDirectory() ? filePath : dirname(filePath);
1373
+ } else {
1374
+ targetDir = originalPathname.endsWith("/") ? filePath : dirname(filePath);
1375
+ }
1376
+ return {
1377
+ filePath,
1378
+ targetDir,
1379
+ stats
1380
+ };
1381
+ }
1382
+ function getMiddlewareDirs(base, parts) {
1383
+ const middlewareDirs = [];
1384
+ let current = base;
1385
+ middlewareDirs.push(current);
1386
+ for (const part of parts) {
1387
+ current = join(current, part);
1388
+ middlewareDirs.push(current);
1389
+ }
1390
+ return middlewareDirs;
1391
+ }
1392
+ async function collectMiddlewares(dirs) {
1393
+ const middlewares = [];
1394
+ for (const dir of dirs) {
1395
+ const mwPath = join(dir, "middleware.ts");
1396
+ let mwModule;
1397
+ try {
1398
+ await fs2.access(mwPath);
1399
+ const url = pathToFileURL(mwPath).href;
1400
+ mwModule = await import(url);
1401
+ } catch {
1402
+ continue;
1403
+ }
1404
+ const mwKeys = Object.keys(mwModule).sort();
1405
+ for (const key of mwKeys) {
1406
+ const f = mwModule[key];
1407
+ if (typeof f === "function" && !middlewares.some((existing) => existing === f)) {
1408
+ middlewares.push(f);
1409
+ }
1410
+ }
1411
+ }
1412
+ return middlewares;
1413
+ }
1414
+ async function handlePageRequest(root, pagesDirectory, pathname, req, res, DIST_DIR2, pageInfo) {
1415
+ try {
1416
+ const {
1417
+ filePath,
1418
+ targetDir,
1419
+ stats
1420
+ } = await getTargetInfo(root, pathname);
1421
+ const relDir = targetDir.slice(root.length).replace(/^[\/\\]+/, "");
1422
+ const parts = relDir.split(/[\\/]/).filter(Boolean);
1423
+ const middlewareDirs = getMiddlewareDirs(pagesDirectory, parts);
1424
+ const middlewares = await collectMiddlewares(middlewareDirs);
1425
+ const data = {};
1426
+ const isDynamic = pageInfo.isDynamic;
1427
+ const handlerPath = isDynamic ? pageInfo.filePath : join(filePath, "index.html");
1428
+ let hasHandler = false;
1429
+ try {
1430
+ await fs2.access(handlerPath);
1431
+ hasHandler = true;
1432
+ } catch {
1433
+ }
1434
+ const finalHandler = async (req2, res2) => {
1435
+ if (!hasHandler) {
1436
+ await respondWithErrorPage(root, pathname, 404, req2, res2);
1437
+ return;
1438
+ }
1439
+ if (isDynamic) {
1440
+ try {
1441
+ const {
1442
+ buildDynamicPage: buildDynamicPage2
1443
+ } = await Promise.resolve().then(() => (init_page_compiler(), page_compiler_exports));
1444
+ const result = await buildDynamicPage2(
1445
+ DIST_DIR2,
1446
+ pathname,
1447
+ pageInfo,
1448
+ req2,
1449
+ res2,
1450
+ data
1451
+ );
1452
+ if (result === false) {
1453
+ return;
1454
+ }
1455
+ const {
1456
+ resultHTML
1457
+ } = result;
1458
+ if (resultHTML === false) {
1459
+ return;
1460
+ }
1461
+ await sendResponse(req2, res2, 200, {
1462
+ "Content-Type": MIME_TYPES[".html"]
1463
+ }, resultHTML);
1464
+ } catch (err) {
1465
+ log.error("Error building dynamic page -", err);
1466
+ }
1467
+ } else {
1468
+ const ext = extname(handlerPath).toLowerCase();
1469
+ const contentType = MIME_TYPES[ext] || "application/octet-stream";
1470
+ const fileData = await fs2.readFile(handlerPath);
1471
+ await sendResponse(req2, res2, 200, {
1472
+ "Content-Type": contentType
1473
+ }, fileData);
1474
+ }
1475
+ };
1476
+ const composed = composeMiddlewares(middlewares, finalHandler, {
1477
+ isApi: false,
1478
+ root,
1479
+ pathname,
1480
+ data
1481
+ });
1482
+ await composed(req, res);
1483
+ } catch (err) {
1484
+ if (err.message === "Forbidden") {
1485
+ await sendResponse(req, res, 403, {
1486
+ "Content-Type": "text/plain; charset=utf-8"
1487
+ }, "Forbidden");
1488
+ } else {
1489
+ throw err;
1490
+ }
1491
+ }
1492
+ }
1493
+ async function handleStaticRequest(root, pagesDirectory, pathname, req, res, DIST_DIR2) {
1494
+ try {
1495
+ const {
1496
+ filePath,
1497
+ targetDir,
1498
+ stats
1499
+ } = await getTargetInfo(root, pathname);
1500
+ const relDir = targetDir.slice(root.length).replace(/^[\/\\]+/, "");
1501
+ const parts = relDir.split(/[\\/]/).filter(Boolean);
1502
+ const middlewareDirs = getMiddlewareDirs(pagesDirectory, parts);
1503
+ const middlewares = await collectMiddlewares(middlewareDirs);
1504
+ let handlerPath = filePath;
1505
+ if (stats && stats.isDirectory()) {
1506
+ handlerPath = join(filePath, "index.html");
1507
+ }
1508
+ let hasHandler = false;
1509
+ try {
1510
+ await fs2.access(handlerPath);
1511
+ hasHandler = true;
1512
+ } catch {
1513
+ }
1514
+ const finalHandler = async (req2, res2) => {
1515
+ if (!hasHandler) {
1516
+ await respondWithErrorPage(root, pathname, 404, req2, res2);
1517
+ return;
1518
+ }
1519
+ const ext = extname(handlerPath).toLowerCase();
1520
+ const contentType = MIME_TYPES[ext] || "application/octet-stream";
1521
+ const fileData = await fs2.readFile(handlerPath);
1522
+ await sendResponse(req2, res2, 200, {
1523
+ "Content-Type": contentType
1524
+ }, fileData);
1525
+ };
1526
+ const composed = composeMiddlewares(middlewares, finalHandler, {
1527
+ isApi: false,
1528
+ root,
1529
+ pathname
1530
+ });
1531
+ await composed(req, res);
1532
+ } catch (err) {
1533
+ if (err.message === "Forbidden") {
1534
+ await sendResponse(req, res, 403, {
1535
+ "Content-Type": "text/plain; charset=utf-8"
1536
+ }, "Forbidden");
1537
+ } else {
1538
+ throw err;
1539
+ }
1540
+ }
1541
+ }
1542
+ async function handleApiRequest(pagesDirectory, pathname, req, res) {
1543
+ const apiSubPath = pathname.slice("/api/".length);
1544
+ const parts = apiSubPath.split("/").filter(Boolean);
1545
+ const middlewareDirs = getMiddlewareDirs(join(pagesDirectory, "api"), parts);
1546
+ const middlewares = await collectMiddlewares(middlewareDirs);
1547
+ const routeDir = middlewareDirs[middlewareDirs.length - 1];
1548
+ const routePath = join(routeDir, "route.ts");
1549
+ let hasRoute = false;
1550
+ try {
1551
+ await fs2.access(routePath);
1552
+ hasRoute = true;
1553
+ } catch {
1554
+ }
1555
+ let fn = null;
1556
+ let module = null;
1557
+ if (hasRoute) {
1558
+ try {
1559
+ const moduleUrl = pathToFileURL(routePath).href;
1560
+ module = await import(moduleUrl);
1561
+ fn = module[req.method];
1562
+ } catch (err) {
1563
+ console.error(err);
1564
+ return respondWithJsonError(req, res, 500, "Internal Server Error");
1565
+ }
1566
+ }
1567
+ const finalHandler = async (req2, res2) => {
1568
+ if (!hasRoute) {
1569
+ return respondWithJsonError(req2, res2, 404, "Not Found");
1570
+ }
1571
+ if (typeof fn !== "function") {
1572
+ return respondWithJsonError(req2, res2, 405, "Method Not Allowed");
1573
+ }
1574
+ await fn(req2, res2);
1575
+ };
1576
+ const composed = composeMiddlewares(middlewares, finalHandler, {
1577
+ isApi: true
1578
+ });
1579
+ await composed(req, res);
1580
+ }
1581
+ function composeMiddlewares(mws, final, options3) {
1582
+ return async function(req, res) {
1583
+ let index = 0;
1584
+ async function dispatch(err) {
1585
+ if (err) {
1586
+ if (options3.isApi) {
1587
+ return respondWithJsonError(req, res, 500, err.message || "Internal Server Error");
1588
+ } else {
1589
+ return await respondWithErrorPage(options3.root, options3.pathname, 500, req, res);
1590
+ }
1591
+ }
1592
+ if (index >= mws.length) {
1593
+ return await final(req, res);
1594
+ }
1595
+ const thisMw = mws[index++];
1596
+ const next = (e) => dispatch(e);
1597
+ const onceNext = (nextFn) => {
1598
+ let called = false;
1599
+ return async (e) => {
1600
+ if (called) {
1601
+ log.warn("next() was called in a middleware more than once.");
1602
+ return;
1603
+ }
1604
+ called = true;
1605
+ await nextFn(e);
1606
+ };
1607
+ };
1608
+ try {
1609
+ await thisMw(req, res, onceNext(next), options3.data || {});
1610
+ } catch (error) {
1611
+ await dispatch(error);
1612
+ }
1613
+ }
1614
+ await dispatch();
1615
+ };
1616
+ }
1617
+ async function respondWithJsonError(req, res, code, message) {
1618
+ const body2 = JSON.stringify({
1619
+ error: message
1620
+ });
1621
+ await sendResponse(req, res, code, {
1622
+ "Content-Type": "application/json; charset=utf-8"
1623
+ }, body2);
1624
+ }
1625
+ async function respondWithErrorPage(root, pathname, code, req, res) {
1626
+ let currentPath = normalize(join(root, decodeURIComponent(pathname)));
1627
+ let tried = /* @__PURE__ */ new Set();
1628
+ let errorFilePath = null;
1629
+ while (currentPath.startsWith(root)) {
1630
+ const candidate = join(currentPath, `${code}.html`);
1631
+ if (!tried.has(candidate)) {
1632
+ try {
1633
+ await fs2.access(candidate);
1634
+ errorFilePath = candidate;
1635
+ break;
1636
+ } catch {
1637
+ }
1638
+ tried.add(candidate);
1639
+ }
1640
+ const parent = dirname(currentPath);
1641
+ if (parent === currentPath) break;
1642
+ currentPath = parent;
1643
+ }
1644
+ if (!errorFilePath) {
1645
+ const fallback = join(root, `${code}.html`);
1646
+ try {
1647
+ await fs2.access(fallback);
1648
+ errorFilePath = fallback;
1649
+ } catch {
1650
+ }
1651
+ }
1652
+ if (errorFilePath) {
1653
+ try {
1654
+ const html2 = await fs2.readFile(errorFilePath, "utf8");
1655
+ await sendResponse(req, res, code, {
1656
+ "Content-Type": "text/html; charset=utf-8"
1657
+ }, html2);
1658
+ return;
1659
+ } catch {
1660
+ }
1661
+ }
1662
+ await sendResponse(req, res, code, {
1663
+ "Content-Type": "text/plain; charset=utf-8"
1664
+ }, `${code} Error`);
1665
+ }
1666
+ function isCompressible(contentType) {
1667
+ if (!contentType) return false;
1668
+ return /text\/|javascript|json|xml|svg/.test(contentType);
1669
+ }
1670
+ async function sendResponse(req, res, status, headers, body2) {
1671
+ let bufferBody = typeof body2 === "string" ? Buffer.from(body2) : body2;
1672
+ const accept = req.headers["accept-encoding"] || "";
1673
+ let encoding = null;
1674
+ if (accept.match(/\bgzip\b/)) {
1675
+ encoding = "gzip";
1676
+ } else if (accept.match(/\bdeflate\b/)) {
1677
+ encoding = "deflate";
1678
+ }
1679
+ if (!encoding || !isCompressible(headers["Content-Type"] || "")) {
1680
+ res.writeHead(status, headers);
1681
+ res.end(bufferBody);
1682
+ return;
1683
+ }
1684
+ const compressor = encoding === "gzip" ? gzipAsync : deflateAsync;
1685
+ try {
1686
+ const compressed = await compressor(bufferBody);
1687
+ headers["Content-Encoding"] = encoding;
1688
+ headers["Vary"] = "Accept-Encoding";
1689
+ res.writeHead(status, headers);
1690
+ res.end(compressed);
1691
+ } catch (err) {
1692
+ log.error("Compression error:", err);
1693
+ res.writeHead(status, headers);
1694
+ res.end(bufferBody);
1695
+ }
1696
+ }
1697
+
44
1698
  // src/build.ts
45
- var __filename = fileURLToPath(import.meta.url);
46
- var __dirname = path.dirname(__filename);
47
- var packageDir = path.resolve(__dirname, "..");
48
- var builderPath = path.resolve(packageDir, "./dist/page_compiler.mjs");
49
- var yellow = (text) => {
1699
+ var __filename2 = fileURLToPath3(import.meta.url);
1700
+ var __dirname2 = path2.dirname(__filename2);
1701
+ var packageDir2 = path2.resolve(__dirname2, "..");
1702
+ var builderPath = path2.resolve(packageDir2, "./dist/page_compiler.mjs");
1703
+ var yellow2 = (text) => {
50
1704
  return `\x1B[38;2;238;184;68m${text}`;
51
1705
  };
52
- var bold = (text) => {
1706
+ var bold2 = (text) => {
53
1707
  return `\x1B[1m${text}`;
54
1708
  };
55
- var white = (text) => {
1709
+ var white2 = (text) => {
56
1710
  return `\x1B[38;2;255;247;229m${text}`;
57
1711
  };
58
1712
  var green = (text) => {
@@ -61,24 +1715,26 @@ var green = (text) => {
61
1715
  var finishLog = (...text) => {
62
1716
  log.info(text.map((text2) => `${text2}\x1B[0m`).join(""));
63
1717
  };
64
- var options = process.env.OPTIONS;
65
- var getAllSubdirectories = (dir, baseDir = dir) => {
1718
+ var PAGE_MAP2 = /* @__PURE__ */ new Map();
1719
+ var LAYOUT_MAP3 = /* @__PURE__ */ new Map();
1720
+ var options2 = process.env.OPTIONS;
1721
+ var getAllSubdirectories2 = (dir, baseDir = dir) => {
66
1722
  let directories = [];
67
- const items = fs.readdirSync(dir, { withFileTypes: true });
1723
+ const items = fs3.readdirSync(dir, { withFileTypes: true });
68
1724
  for (const item of items) {
69
1725
  if (item.isDirectory()) {
70
- const fullPath = path.join(dir, item.name);
71
- const relativePath = path.relative(baseDir, fullPath);
1726
+ const fullPath = path2.join(dir, item.name);
1727
+ const relativePath = path2.relative(baseDir, fullPath);
72
1728
  directories.push(relativePath);
73
- directories = directories.concat(getAllSubdirectories(fullPath, baseDir));
1729
+ directories = directories.concat(getAllSubdirectories2(fullPath, baseDir));
74
1730
  }
75
1731
  }
76
1732
  return directories;
77
1733
  };
78
1734
  var child = void 0;
79
1735
  var isBuilding = false;
80
- var runBuild = (filepath, DIST_DIR) => {
81
- const optionsString = JSON.stringify(options);
1736
+ var runBuild = (filepath, DIST_DIR2) => {
1737
+ const optionsString = JSON.stringify(options2);
82
1738
  if (isBuilding) {
83
1739
  return;
84
1740
  }
@@ -88,8 +1744,16 @@ var runBuild = (filepath, DIST_DIR) => {
88
1744
  }
89
1745
  child = child_process.spawn("node", [filepath], {
90
1746
  stdio: ["inherit", "inherit", "inherit", "ipc"],
91
- env: { ...process.env, DIST_DIR, OPTIONS: optionsString, PACKAGE_PATH: packageDir }
1747
+ env: {
1748
+ ...process.env,
1749
+ DIST_DIR: DIST_DIR2,
1750
+ OPTIONS: optionsString,
1751
+ PACKAGE_PATH: packageDir2,
1752
+ DO_BUILD: "true"
1753
+ }
92
1754
  });
1755
+ process.env.OPTIONS = optionsString;
1756
+ process.env.DIST_DIR = DIST_DIR2;
93
1757
  child.on("error", () => {
94
1758
  log.error("Failed to start child process.");
95
1759
  });
@@ -109,17 +1773,21 @@ var runBuild = (filepath, DIST_DIR) => {
109
1773
  `);
110
1774
  } else if (data === "compile-finish") {
111
1775
  isBuilding = false;
112
- if (options.postCompile) {
1776
+ if (options2.postCompile) {
113
1777
  finishLog(
114
- white("Calling post-compile hook..")
1778
+ white2("Calling post-compile hook..")
115
1779
  );
116
- options.postCompile();
1780
+ options2.postCompile();
117
1781
  }
1782
+ } else if (data === "set-pages-and-layouts") {
1783
+ const { pageMap, layoutMap } = JSON.parse(message.content);
1784
+ PAGE_MAP2 = new Map(pageMap);
1785
+ LAYOUT_MAP3 = new Map(layoutMap);
118
1786
  }
119
1787
  });
120
1788
  };
121
- var build = (DIST_DIR) => {
122
- runBuild(builderPath, DIST_DIR);
1789
+ var build2 = (DIST_DIR2) => {
1790
+ runBuild(builderPath, DIST_DIR2);
123
1791
  };
124
1792
  var isTimedOut = false;
125
1793
  var currentWatchers = [];
@@ -127,7 +1795,7 @@ var httpStream;
127
1795
  var registerListener = async () => {
128
1796
  const server = http.createServer((req, res) => {
129
1797
  if (req.url === "/events") {
130
- finishLog(white("Client listening for changes.."));
1798
+ finishLog(white2("Client listening for changes.."));
131
1799
  res.writeHead(200, {
132
1800
  "Content-Type": "text/event-stream",
133
1801
  "Cache-Control": "no-cache",
@@ -148,30 +1816,40 @@ var registerListener = async () => {
148
1816
  res.end("Not Found");
149
1817
  }
150
1818
  });
151
- server.listen(options.hotReload.port, () => {
152
- finishLog(bold(green("Hot-Reload server online!")));
1819
+ server.listen(options2.hotReload.port, () => {
1820
+ finishLog(bold2(green("Hot-Reload server online!")));
153
1821
  });
154
1822
  };
155
1823
  var compile = async (props) => {
156
- options = props;
157
- setQuiet(options.quiet ?? false);
158
- const watch = options.hotReload !== void 0;
159
- const BUILD_FLAG = path.join(options.outputDirectory, "ELEGANCE_BUILD_FLAG");
160
- if (!fs.existsSync(options.outputDirectory)) {
161
- fs.mkdirSync(options.outputDirectory, { recursive: true });
162
- fs.writeFileSync(
163
- path.join(BUILD_FLAG),
1824
+ options2 = props;
1825
+ setQuiet(options2.quiet ?? false);
1826
+ const watch = options2.hotReload !== void 0;
1827
+ const BUILD_FLAG = path2.join(options2.outputDirectory, "ELEGANCE_BUILD_FLAG");
1828
+ if (!fs3.existsSync(options2.outputDirectory)) {
1829
+ fs3.mkdirSync(options2.outputDirectory, { recursive: true });
1830
+ fs3.writeFileSync(
1831
+ path2.join(BUILD_FLAG),
164
1832
  "This file just marks this directory as one containing an Elegance Build.",
165
1833
  "utf-8"
166
1834
  );
167
1835
  } else {
168
- if (!fs.existsSync(BUILD_FLAG)) {
1836
+ if (!fs3.existsSync(BUILD_FLAG)) {
169
1837
  throw `The output directory already exists, but is not an Elegance Build directory.`;
170
1838
  }
171
1839
  }
172
- const DIST_DIR = path.join(props.outputDirectory, "dist");
173
- if (!fs.existsSync(DIST_DIR)) {
174
- fs.mkdirSync(DIST_DIR, { recursive: true });
1840
+ const DIST_DIR2 = path2.join(props.outputDirectory, "dist");
1841
+ if (!fs3.existsSync(DIST_DIR2)) {
1842
+ fs3.mkdirSync(DIST_DIR2, { recursive: true });
1843
+ }
1844
+ if (options2.server != void 0 && options2.server.runServer == true) {
1845
+ startServer({
1846
+ root: options2.server.root ?? DIST_DIR2,
1847
+ environment: options2.environment,
1848
+ port: options2.server.port ?? 3e3,
1849
+ host: options2.server.host ?? "localhost",
1850
+ DIST_DIR: DIST_DIR2,
1851
+ pagesDirectory: options2.pagesDirectory
1852
+ });
175
1853
  }
176
1854
  if (watch) {
177
1855
  await registerListener();
@@ -179,29 +1857,29 @@ var compile = async (props) => {
179
1857
  watcher.close();
180
1858
  }
181
1859
  let extra = [];
182
- if (options.hotReload?.extraWatchDirectories) {
183
- const dirs = options.hotReload?.extraWatchDirectories ?? [];
1860
+ if (options2.hotReload?.extraWatchDirectories) {
1861
+ const dirs = options2.hotReload?.extraWatchDirectories ?? [];
184
1862
  if (dirs.length !== 0) {
185
1863
  for (const dir of dirs) {
186
- const subdirs = getAllSubdirectories(dir).map((f) => path.join(dir, f));
1864
+ const subdirs = getAllSubdirectories2(dir).map((f) => path2.join(dir, f));
187
1865
  extra.push(...subdirs);
188
1866
  }
189
1867
  }
190
1868
  }
191
- const pagesSubDirs = getAllSubdirectories(options.pagesDirectory).map((f) => path.join(options.pagesDirectory, f));
192
- const subdirectories = [...pagesSubDirs, options.pagesDirectory, ...extra];
193
- finishLog(yellow("Hot-Reload Watching Subdirectories: "), ...subdirectories.join(", "));
1869
+ const pagesSubDirs = getAllSubdirectories2(options2.pagesDirectory).map((f) => path2.join(options2.pagesDirectory, f));
1870
+ const subdirectories = [...pagesSubDirs, options2.pagesDirectory, ...extra];
1871
+ finishLog(yellow2("Hot-Reload Watching Subdirectories: "), ...subdirectories.join(", "));
194
1872
  const watcherFn = async () => {
195
1873
  if (isTimedOut) return;
196
1874
  isTimedOut = true;
197
1875
  process.stdout.write("\x1Bc");
198
1876
  setTimeout(async () => {
199
- build(DIST_DIR);
1877
+ build2(DIST_DIR2);
200
1878
  isTimedOut = false;
201
1879
  }, 100);
202
1880
  };
203
1881
  for (const directory of subdirectories) {
204
- const watcher = fs.watch(
1882
+ const watcher = fs3.watch(
205
1883
  directory,
206
1884
  {},
207
1885
  watcherFn
@@ -209,8 +1887,10 @@ var compile = async (props) => {
209
1887
  currentWatchers.push(watcher);
210
1888
  }
211
1889
  }
212
- build(DIST_DIR);
1890
+ build2(DIST_DIR2);
213
1891
  };
214
1892
  export {
1893
+ LAYOUT_MAP3 as LAYOUT_MAP,
1894
+ PAGE_MAP2 as PAGE_MAP,
215
1895
  compile
216
1896
  };