elegance-js 2.1.9 → 2.1.11
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 +72 -1763
- package/dist/client/client.mjs +36 -165
- package/dist/client/processPageElements.mjs +7 -7
- package/dist/client/render.mjs +1 -2
- package/dist/client/watcher.mjs +1 -2
- package/dist/compile_docs.mjs +8 -1902
- package/dist/components/Link.mjs +3 -51
- package/dist/helpers/ObjectAttributeType.mjs +0 -1
- package/dist/helpers/camelToKebab.mjs +1 -2
- package/dist/index.mjs +3 -215
- package/dist/internal/deprecate.mjs +1 -2
- package/dist/log.mjs +2 -3
- package/dist/page_compiler.mjs +51 -320
- package/dist/server/generateHTMLTemplate.mjs +2 -194
- package/dist/server/layout.mjs +3 -4
- package/dist/server/loadHook.mjs +5 -11
- package/dist/server/observe.mjs +3 -3
- package/dist/server/render.mjs +3 -149
- package/dist/server/server.mjs +38 -1290
- package/dist/server/state.mjs +13 -34
- package/dist/shared/bindServerElements.mjs +1 -143
- package/dist/shared/serverElements.mjs +8 -9
- package/package.json +3 -3
package/dist/server/server.mjs
CHANGED
|
@@ -1,1219 +1,8 @@
|
|
|
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 child of element.children) {
|
|
214
|
-
returnString += renderRecursively(child);
|
|
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
|
-
});
|
|
342
|
-
import fs from "fs";
|
|
343
|
-
import path2 from "path";
|
|
344
|
-
import { registerLoader, setArcTsConfig } from "ts-arc";
|
|
345
|
-
import esbuild from "esbuild";
|
|
346
|
-
import { fileURLToPath as fileURLToPath2 } 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 child = 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 === child);
|
|
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 __filename2, __dirname2, packageDir2, clientPath, watcherPath, shippedModules, modulesToShip, yellow, black, bgYellow, bold, underline, white, log2, options2, DIST_DIR, PAGE_MAP2, 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
|
-
__filename2 = fileURLToPath2(import.meta.url);
|
|
394
|
-
__dirname2 = path2.dirname(__filename2);
|
|
395
|
-
setArcTsConfig(__dirname2);
|
|
396
|
-
registerLoader();
|
|
397
|
-
packageDir2 = process.env.PACKAGE_PATH;
|
|
398
|
-
if (packageDir2 === void 0) {
|
|
399
|
-
packageDir2 = path2.resolve(__dirname2, "..");
|
|
400
|
-
}
|
|
401
|
-
clientPath = path2.resolve(packageDir2, "./dist/client/client.mjs");
|
|
402
|
-
watcherPath = path2.resolve(packageDir2, "./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 (options2.quiet) return;
|
|
425
|
-
return console.log(text.map((text2) => `${text2}\x1B[0m`).join(""));
|
|
426
|
-
};
|
|
427
|
-
options2 = JSON.parse(process.env.OPTIONS || "{}");
|
|
428
|
-
console.log(options2);
|
|
429
|
-
DIST_DIR = process.env.DIST_DIR;
|
|
430
|
-
PAGE_MAP2 = /* @__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 = path2.join(dir, item.name);
|
|
438
|
-
const relativePath = path2.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 (options2.hotReload !== void 0) {
|
|
449
|
-
clientString += `const watchServerPort = ${options2.hotReload.port}`;
|
|
450
|
-
clientString += fs.readFileSync(watcherPath, "utf-8");
|
|
451
|
-
}
|
|
452
|
-
const transformedClient = await esbuild.transform(clientString, {
|
|
453
|
-
minify: options2.environment === "production",
|
|
454
|
-
drop: options2.environment === "production" ? ["console", "debugger"] : void 0,
|
|
455
|
-
keepNames: false,
|
|
456
|
-
format: "iife",
|
|
457
|
-
platform: "node",
|
|
458
|
-
loader: "ts"
|
|
459
|
-
});
|
|
460
|
-
fs.writeFileSync(
|
|
461
|
-
path2.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 child = element.children[i];
|
|
532
|
-
const processedChild = processPageElements(child, 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 child = element.children[i];
|
|
586
|
-
const processedChild = processPageElements(child, 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: options2.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 = path2.join(pageLocation, (pageName === "page" ? "index" : pageName) + ".html");
|
|
663
|
-
if (doWrite) {
|
|
664
|
-
const dirname2 = path2.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 = path2.join(DIST_DIR2, pageLocation, `${pageName}_data.js`);
|
|
734
|
-
let sendHardReloadInstruction = false;
|
|
735
|
-
const transformedResult = await esbuild.transform(clientPageJSText, { minify: options2.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 = path2.resolve(options2.pagesDirectory);
|
|
832
|
-
const subdirectories = [...getAllSubdirectories(pagesDirectory), ""];
|
|
833
|
-
let shouldClientHardReload = false;
|
|
834
|
-
for (const directory of subdirectories) {
|
|
835
|
-
const abs = path2.resolve(path2.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 = path2.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 = path2.relative(options2.pagesDirectory, dirname2);
|
|
893
|
-
let split = relative2.split(path2.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 = path2.join(path2.resolve(options2.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 = path2.resolve(options2.pagesDirectory);
|
|
931
|
-
const subdirectories = [...getAllSubdirectories(pagesDirectory), ""];
|
|
932
|
-
let shouldClientHardReload = false;
|
|
933
|
-
for (const directory of subdirectories) {
|
|
934
|
-
const abs = path2.resolve(path2.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 = path2.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_MAP2.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(path2.dirname(filePath));
|
|
1021
|
-
const foundObjectAttributes = await pageToHTML(
|
|
1022
|
-
path2.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(path2.dirname(filePath));
|
|
1104
|
-
const resultHTML = await pageToHTML(
|
|
1105
|
-
path2.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: path2.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 (options2.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 (options2.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 (options2.preCompile) {
|
|
1162
|
-
options2.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(path2.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 (options2.publicDirectory) {
|
|
1179
|
-
log2("Recursively copying public directory.. this may take a while.");
|
|
1180
|
-
const src = path2.relative(process.cwd(), options2.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, path2.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_MAP2), 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/server/server.ts
|
|
1212
1
|
import {
|
|
1213
2
|
createServer as createHttpServer
|
|
1214
3
|
} from "http";
|
|
1215
4
|
import {
|
|
1216
|
-
promises as
|
|
5
|
+
promises as fs
|
|
1217
6
|
} from "fs";
|
|
1218
7
|
import {
|
|
1219
8
|
join,
|
|
@@ -1224,41 +13,9 @@ import {
|
|
|
1224
13
|
import {
|
|
1225
14
|
pathToFileURL
|
|
1226
15
|
} from "url";
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
function getTimestamp() {
|
|
1231
|
-
const now = /* @__PURE__ */ new Date();
|
|
1232
|
-
return now.toLocaleString(void 0, {
|
|
1233
|
-
year: "2-digit",
|
|
1234
|
-
month: "2-digit",
|
|
1235
|
-
day: "2-digit",
|
|
1236
|
-
hour: "2-digit",
|
|
1237
|
-
minute: "2-digit",
|
|
1238
|
-
second: "2-digit"
|
|
1239
|
-
});
|
|
1240
|
-
}
|
|
1241
|
-
function color(text, code) {
|
|
1242
|
-
return `\x1B[${code}m${text}\x1B[0m`;
|
|
1243
|
-
}
|
|
1244
|
-
function logInfo(...args) {
|
|
1245
|
-
if (quiet) return;
|
|
1246
|
-
console.info(`Elegance.JS: ${getTimestamp()} ${color("[INFO]:", 34)}`, ...args);
|
|
1247
|
-
}
|
|
1248
|
-
function logWarn(...args) {
|
|
1249
|
-
if (quiet) return;
|
|
1250
|
-
console.warn(`Elegance.JS: ${getTimestamp()} ${color("[WARN]:", 33)}`, ...args);
|
|
1251
|
-
}
|
|
1252
|
-
function logError(...args) {
|
|
1253
|
-
console.error(`Elegance.JS: ${getTimestamp()} ${color("[ERROR]:", 31)}`, ...args);
|
|
1254
|
-
}
|
|
1255
|
-
var log = {
|
|
1256
|
-
info: logInfo,
|
|
1257
|
-
warn: logWarn,
|
|
1258
|
-
error: logError
|
|
1259
|
-
};
|
|
1260
|
-
|
|
1261
|
-
// src/server/server.ts
|
|
16
|
+
import {
|
|
17
|
+
log
|
|
18
|
+
} from "../log";
|
|
1262
19
|
import {
|
|
1263
20
|
gzip,
|
|
1264
21
|
deflate
|
|
@@ -1266,21 +23,12 @@ import {
|
|
|
1266
23
|
import {
|
|
1267
24
|
promisify
|
|
1268
25
|
} from "util";
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
var packageDir = path.resolve(__dirname, "..");
|
|
1276
|
-
var builderPath = path.resolve(packageDir, "./dist/page_compiler.mjs");
|
|
1277
|
-
var PAGE_MAP = /* @__PURE__ */ new Map();
|
|
1278
|
-
var options = process.env.OPTIONS;
|
|
1279
|
-
|
|
1280
|
-
// src/server/server.ts
|
|
1281
|
-
var gzipAsync = promisify(gzip);
|
|
1282
|
-
var deflateAsync = promisify(deflate);
|
|
1283
|
-
var MIME_TYPES = {
|
|
26
|
+
import {
|
|
27
|
+
PAGE_MAP
|
|
28
|
+
} from "../build";
|
|
29
|
+
const gzipAsync = promisify(gzip);
|
|
30
|
+
const deflateAsync = promisify(deflate);
|
|
31
|
+
const MIME_TYPES = {
|
|
1284
32
|
".html": "text/html; charset=utf-8",
|
|
1285
33
|
".css": "text/css; charset=utf-8",
|
|
1286
34
|
".js": "application/javascript; charset=utf-8",
|
|
@@ -1299,7 +47,7 @@ function startServer({
|
|
|
1299
47
|
port = 3e3,
|
|
1300
48
|
host = "localhost",
|
|
1301
49
|
environment = "production",
|
|
1302
|
-
DIST_DIR
|
|
50
|
+
DIST_DIR
|
|
1303
51
|
}) {
|
|
1304
52
|
if (!root) throw new Error("Root directory must be specified.");
|
|
1305
53
|
if (!pagesDirectory) throw new Error("Pages directory must be specified.");
|
|
@@ -1328,9 +76,9 @@ function startServer({
|
|
|
1328
76
|
if (url.pathname.startsWith("/api/")) {
|
|
1329
77
|
await handleApiRequest(pagesDirectory, url.pathname, req, res);
|
|
1330
78
|
} else if (PAGE_MAP.has(url.pathname)) {
|
|
1331
|
-
await handlePageRequest(root, pagesDirectory, url.pathname, req, res,
|
|
79
|
+
await handlePageRequest(root, pagesDirectory, url.pathname, req, res, DIST_DIR, PAGE_MAP.get(url.pathname));
|
|
1332
80
|
} else {
|
|
1333
|
-
await handleStaticRequest(root, pagesDirectory, url.pathname, req, res,
|
|
81
|
+
await handleStaticRequest(root, pagesDirectory, url.pathname, req, res, DIST_DIR);
|
|
1334
82
|
}
|
|
1335
83
|
if (environment === "development") {
|
|
1336
84
|
log.info(req.method, "::", req.url, "-", res.statusCode);
|
|
@@ -1366,7 +114,7 @@ async function getTargetInfo(root, pathname) {
|
|
|
1366
114
|
}
|
|
1367
115
|
let stats;
|
|
1368
116
|
try {
|
|
1369
|
-
stats = await
|
|
117
|
+
stats = await fs.stat(filePath);
|
|
1370
118
|
} catch {
|
|
1371
119
|
}
|
|
1372
120
|
let targetDir;
|
|
@@ -1397,7 +145,7 @@ async function collectMiddlewares(dirs) {
|
|
|
1397
145
|
const mwPath = join(dir, "middleware.ts");
|
|
1398
146
|
let mwModule;
|
|
1399
147
|
try {
|
|
1400
|
-
await
|
|
148
|
+
await fs.access(mwPath);
|
|
1401
149
|
const url = pathToFileURL(mwPath).href;
|
|
1402
150
|
mwModule = await import(url);
|
|
1403
151
|
} catch {
|
|
@@ -1413,7 +161,7 @@ async function collectMiddlewares(dirs) {
|
|
|
1413
161
|
}
|
|
1414
162
|
return middlewares;
|
|
1415
163
|
}
|
|
1416
|
-
async function handlePageRequest(root, pagesDirectory, pathname, req, res,
|
|
164
|
+
async function handlePageRequest(root, pagesDirectory, pathname, req, res, DIST_DIR, pageInfo) {
|
|
1417
165
|
try {
|
|
1418
166
|
const {
|
|
1419
167
|
filePath,
|
|
@@ -1429,7 +177,7 @@ async function handlePageRequest(root, pagesDirectory, pathname, req, res, DIST_
|
|
|
1429
177
|
const handlerPath = isDynamic ? pageInfo.filePath : join(filePath, "index.html");
|
|
1430
178
|
let hasHandler = false;
|
|
1431
179
|
try {
|
|
1432
|
-
await
|
|
180
|
+
await fs.access(handlerPath);
|
|
1433
181
|
hasHandler = true;
|
|
1434
182
|
} catch {
|
|
1435
183
|
}
|
|
@@ -1441,10 +189,10 @@ async function handlePageRequest(root, pagesDirectory, pathname, req, res, DIST_
|
|
|
1441
189
|
if (isDynamic) {
|
|
1442
190
|
try {
|
|
1443
191
|
const {
|
|
1444
|
-
buildDynamicPage
|
|
1445
|
-
} = await
|
|
1446
|
-
const result = await
|
|
1447
|
-
|
|
192
|
+
buildDynamicPage
|
|
193
|
+
} = await import("../page_compiler");
|
|
194
|
+
const result = await buildDynamicPage(
|
|
195
|
+
DIST_DIR,
|
|
1448
196
|
pathname,
|
|
1449
197
|
pageInfo,
|
|
1450
198
|
req2,
|
|
@@ -1469,7 +217,7 @@ async function handlePageRequest(root, pagesDirectory, pathname, req, res, DIST_
|
|
|
1469
217
|
} else {
|
|
1470
218
|
const ext = extname(handlerPath).toLowerCase();
|
|
1471
219
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
1472
|
-
const fileData = await
|
|
220
|
+
const fileData = await fs.readFile(handlerPath);
|
|
1473
221
|
await sendResponse(req2, res2, 200, {
|
|
1474
222
|
"Content-Type": contentType
|
|
1475
223
|
}, fileData);
|
|
@@ -1492,7 +240,7 @@ async function handlePageRequest(root, pagesDirectory, pathname, req, res, DIST_
|
|
|
1492
240
|
}
|
|
1493
241
|
}
|
|
1494
242
|
}
|
|
1495
|
-
async function handleStaticRequest(root, pagesDirectory, pathname, req, res,
|
|
243
|
+
async function handleStaticRequest(root, pagesDirectory, pathname, req, res, DIST_DIR) {
|
|
1496
244
|
try {
|
|
1497
245
|
const {
|
|
1498
246
|
filePath,
|
|
@@ -1509,7 +257,7 @@ async function handleStaticRequest(root, pagesDirectory, pathname, req, res, DIS
|
|
|
1509
257
|
}
|
|
1510
258
|
let hasHandler = false;
|
|
1511
259
|
try {
|
|
1512
|
-
await
|
|
260
|
+
await fs.access(handlerPath);
|
|
1513
261
|
hasHandler = true;
|
|
1514
262
|
} catch {
|
|
1515
263
|
}
|
|
@@ -1520,7 +268,7 @@ async function handleStaticRequest(root, pagesDirectory, pathname, req, res, DIS
|
|
|
1520
268
|
}
|
|
1521
269
|
const ext = extname(handlerPath).toLowerCase();
|
|
1522
270
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
1523
|
-
const fileData = await
|
|
271
|
+
const fileData = await fs.readFile(handlerPath);
|
|
1524
272
|
await sendResponse(req2, res2, 200, {
|
|
1525
273
|
"Content-Type": contentType
|
|
1526
274
|
}, fileData);
|
|
@@ -1550,7 +298,7 @@ async function handleApiRequest(pagesDirectory, pathname, req, res) {
|
|
|
1550
298
|
const routePath = join(routeDir, "route.ts");
|
|
1551
299
|
let hasRoute = false;
|
|
1552
300
|
try {
|
|
1553
|
-
await
|
|
301
|
+
await fs.access(routePath);
|
|
1554
302
|
hasRoute = true;
|
|
1555
303
|
} catch {
|
|
1556
304
|
}
|
|
@@ -1580,15 +328,15 @@ async function handleApiRequest(pagesDirectory, pathname, req, res) {
|
|
|
1580
328
|
});
|
|
1581
329
|
await composed(req, res);
|
|
1582
330
|
}
|
|
1583
|
-
function composeMiddlewares(mws, final,
|
|
331
|
+
function composeMiddlewares(mws, final, options) {
|
|
1584
332
|
return async function(req, res) {
|
|
1585
333
|
let index = 0;
|
|
1586
334
|
async function dispatch(err) {
|
|
1587
335
|
if (err) {
|
|
1588
|
-
if (
|
|
336
|
+
if (options.isApi) {
|
|
1589
337
|
return respondWithJsonError(req, res, 500, err.message || "Internal Server Error");
|
|
1590
338
|
} else {
|
|
1591
|
-
return await respondWithErrorPage(
|
|
339
|
+
return await respondWithErrorPage(options.root, options.pathname, 500, req, res);
|
|
1592
340
|
}
|
|
1593
341
|
}
|
|
1594
342
|
if (index >= mws.length) {
|
|
@@ -1608,7 +356,7 @@ function composeMiddlewares(mws, final, options3) {
|
|
|
1608
356
|
};
|
|
1609
357
|
};
|
|
1610
358
|
try {
|
|
1611
|
-
await thisMw(req, res, onceNext(next),
|
|
359
|
+
await thisMw(req, res, onceNext(next), options.data || {});
|
|
1612
360
|
} catch (error) {
|
|
1613
361
|
await dispatch(error);
|
|
1614
362
|
}
|
|
@@ -1617,12 +365,12 @@ function composeMiddlewares(mws, final, options3) {
|
|
|
1617
365
|
};
|
|
1618
366
|
}
|
|
1619
367
|
async function respondWithJsonError(req, res, code, message) {
|
|
1620
|
-
const
|
|
368
|
+
const body = JSON.stringify({
|
|
1621
369
|
error: message
|
|
1622
370
|
});
|
|
1623
371
|
await sendResponse(req, res, code, {
|
|
1624
372
|
"Content-Type": "application/json; charset=utf-8"
|
|
1625
|
-
},
|
|
373
|
+
}, body);
|
|
1626
374
|
}
|
|
1627
375
|
async function respondWithErrorPage(root, pathname, code, req, res) {
|
|
1628
376
|
let currentPath = normalize(join(root, decodeURIComponent(pathname)));
|
|
@@ -1632,7 +380,7 @@ async function respondWithErrorPage(root, pathname, code, req, res) {
|
|
|
1632
380
|
const candidate = join(currentPath, `${code}.html`);
|
|
1633
381
|
if (!tried.has(candidate)) {
|
|
1634
382
|
try {
|
|
1635
|
-
await
|
|
383
|
+
await fs.access(candidate);
|
|
1636
384
|
errorFilePath = candidate;
|
|
1637
385
|
break;
|
|
1638
386
|
} catch {
|
|
@@ -1646,17 +394,17 @@ async function respondWithErrorPage(root, pathname, code, req, res) {
|
|
|
1646
394
|
if (!errorFilePath) {
|
|
1647
395
|
const fallback = join(root, `${code}.html`);
|
|
1648
396
|
try {
|
|
1649
|
-
await
|
|
397
|
+
await fs.access(fallback);
|
|
1650
398
|
errorFilePath = fallback;
|
|
1651
399
|
} catch {
|
|
1652
400
|
}
|
|
1653
401
|
}
|
|
1654
402
|
if (errorFilePath) {
|
|
1655
403
|
try {
|
|
1656
|
-
const
|
|
404
|
+
const html = await fs.readFile(errorFilePath, "utf8");
|
|
1657
405
|
await sendResponse(req, res, code, {
|
|
1658
406
|
"Content-Type": "text/html; charset=utf-8"
|
|
1659
|
-
},
|
|
407
|
+
}, html);
|
|
1660
408
|
return;
|
|
1661
409
|
} catch {
|
|
1662
410
|
}
|
|
@@ -1669,8 +417,8 @@ function isCompressible(contentType) {
|
|
|
1669
417
|
if (!contentType) return false;
|
|
1670
418
|
return /text\/|javascript|json|xml|svg/.test(contentType);
|
|
1671
419
|
}
|
|
1672
|
-
async function sendResponse(req, res, status, headers,
|
|
1673
|
-
let bufferBody = typeof
|
|
420
|
+
async function sendResponse(req, res, status, headers, body) {
|
|
421
|
+
let bufferBody = typeof body === "string" ? Buffer.from(body) : body;
|
|
1674
422
|
const accept = req.headers["accept-encoding"] || "";
|
|
1675
423
|
let encoding = null;
|
|
1676
424
|
if (accept.match(/\bgzip\b/)) {
|