elegance-js 2.1.23 → 2.1.26
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/client/effect.d.ts +27 -0
- package/dist/client/effect.js +37 -0
- package/dist/client/eventListener.d.ts +39 -0
- package/dist/client/eventListener.js +52 -0
- package/dist/client/loadHook.d.ts +34 -0
- package/dist/client/loadHook.js +52 -0
- package/dist/client/observer.d.ts +36 -0
- package/dist/client/observer.js +66 -0
- package/dist/client/runtime.d.ts +105 -0
- package/dist/client/runtime.js +620 -0
- package/dist/client/state.d.ts +40 -0
- package/dist/client/state.js +110 -0
- package/dist/compilation/compiler.d.ts +155 -0
- package/dist/compilation/compiler.js +1153 -0
- package/dist/components/ClientComponent.d.ts +22 -0
- package/dist/components/ClientComponent.js +55 -0
- package/dist/components/Link.d.ts +16 -1
- package/dist/components/Link.js +22 -0
- package/dist/components/Portal.d.ts +2 -0
- package/dist/components/Portal.js +2 -0
- package/dist/elements/element.d.ts +87 -0
- package/dist/elements/element.js +33 -0
- package/dist/elements/element_list.d.ts +7 -0
- package/dist/elements/element_list.js +65 -0
- package/dist/elements/raw.d.ts +14 -0
- package/dist/elements/raw.js +78 -0
- package/dist/elements/specific_props.d.ts +750 -0
- package/dist/global.d.ts +221 -327
- package/dist/index.d.ts +15 -3
- package/dist/index.js +11 -0
- package/dist/server/layout.d.ts +34 -3
- package/dist/server/layout.js +6 -0
- package/dist/server/log.d.ts +12 -0
- package/dist/server/log.js +64 -0
- package/dist/server/page.d.ts +32 -0
- package/dist/server/page.js +6 -0
- package/dist/server/runtime.d.ts +6 -0
- package/dist/server/runtime.js +72 -0
- package/dist/server/server.d.ts +103 -11
- package/dist/server/server.js +709 -0
- package/package.json +13 -13
- package/scripts/bootstrap.js +37 -273
- package/scripts/bootstrap_files/elegance.txt +40 -0
- package/scripts/bootstrap_files/index.txt +3 -0
- package/scripts/bootstrap_files/layout.txt +46 -0
- package/scripts/bootstrap_files/middleware.txt +18 -0
- package/scripts/bootstrap_files/page.txt +123 -0
- package/scripts/bootstrap_files/route.txt +6 -0
- package/scripts/elegance_dev.ts +40 -0
- package/scripts/elegance_prod.ts +40 -0
- package/scripts/elegance_static.ts +24 -0
- package/scripts/prod.js +9 -26
- package/scripts/run.js +13 -0
- package/scripts/static.js +13 -0
- package/dist/build.d.ts +0 -2
- package/dist/build.mjs +0 -202
- package/dist/client/client.d.ts +0 -1
- package/dist/client/client.mjs +0 -574
- package/dist/client/processPageElements.d.ts +0 -1
- package/dist/client/processPageElements.mjs +0 -117
- package/dist/client/render.d.ts +0 -1
- package/dist/client/render.mjs +0 -40
- package/dist/client/watcher.d.ts +0 -1
- package/dist/client/watcher.mjs +0 -26
- package/dist/compilation/compilation.d.ts +0 -139
- package/dist/compilation/compilation.mjs +0 -751
- package/dist/compilation/compiler_process.d.ts +0 -3
- package/dist/compilation/compiler_process.mjs +0 -102
- package/dist/compilation/dynamic_compiler.d.ts +0 -10
- package/dist/compilation/dynamic_compiler.mjs +0 -93
- package/dist/compile_docs.mjs +0 -34
- package/dist/components/Link.mjs +0 -65
- package/dist/global.mjs +0 -0
- package/dist/helpers/ObjectAttributeType.d.ts +0 -7
- package/dist/helpers/ObjectAttributeType.mjs +0 -11
- package/dist/helpers/camelToKebab.d.ts +0 -1
- package/dist/helpers/camelToKebab.mjs +0 -6
- package/dist/index.mjs +0 -3
- package/dist/internal/deprecate.d.ts +0 -1
- package/dist/internal/deprecate.mjs +0 -7
- package/dist/log.d.ts +0 -10
- package/dist/log.mjs +0 -38
- package/dist/server/generateHTMLTemplate.d.ts +0 -12
- package/dist/server/generateHTMLTemplate.mjs +0 -41
- package/dist/server/layout.mjs +0 -19
- package/dist/server/loadHook.d.ts +0 -30
- package/dist/server/loadHook.mjs +0 -50
- package/dist/server/observe.d.ts +0 -19
- package/dist/server/observe.mjs +0 -16
- package/dist/server/render.d.ts +0 -5
- package/dist/server/render.mjs +0 -61
- package/dist/server/server.mjs +0 -429
- package/dist/server/state.d.ts +0 -61
- package/dist/server/state.mjs +0 -146
- package/dist/shared/bindServerElements.mjs +0 -3
- package/dist/shared/serverElements.d.ts +0 -11
- package/dist/shared/serverElements.mjs +0 -164
- package/scripts/dev.js +0 -33
- package/scripts/export.js +0 -20
- package/scripts/ts-arc-dev.js +0 -9
- package/scripts/ts-arc-prod.js +0 -9
- /package/dist/{compile_docs.d.ts → elements/specific_props.js} +0 -0
- /package/dist/{shared/bindServerElements.d.ts → global.js} +0 -0
package/dist/server/server.mjs
DELETED
|
@@ -1,429 +0,0 @@
|
|
|
1
|
-
import { createServer as createHttpServer } from "http";
|
|
2
|
-
import { promises as fs } from "fs";
|
|
3
|
-
import { join, normalize, extname, dirname } from "path";
|
|
4
|
-
import { pathToFileURL } from "url";
|
|
5
|
-
import { log } from "../log";
|
|
6
|
-
import { gzip, deflate } from "zlib";
|
|
7
|
-
import { promisify } from "util";
|
|
8
|
-
import { doesPageExist, getPage } from "../compilation/dynamic_compiler";
|
|
9
|
-
const gzipAsync = promisify(gzip);
|
|
10
|
-
const deflateAsync = promisify(deflate);
|
|
11
|
-
const MIME_TYPES = {
|
|
12
|
-
".html": "text/html; charset=utf-8",
|
|
13
|
-
".css": "text/css; charset=utf-8",
|
|
14
|
-
".js": "application/javascript; charset=utf-8",
|
|
15
|
-
".json": "application/json; charset=utf-8",
|
|
16
|
-
".png": "image/png",
|
|
17
|
-
".jpg": "image/jpeg",
|
|
18
|
-
".jpeg": "image/jpeg",
|
|
19
|
-
".gif": "image/gif",
|
|
20
|
-
".svg": "image/svg+xml",
|
|
21
|
-
".ico": "image/x-icon",
|
|
22
|
-
".txt": "text/plain; charset=utf-8"
|
|
23
|
-
};
|
|
24
|
-
function startServer({
|
|
25
|
-
root,
|
|
26
|
-
pagesDirectory,
|
|
27
|
-
port = 3e3,
|
|
28
|
-
host = "localhost",
|
|
29
|
-
environment = "production",
|
|
30
|
-
DIST_DIR
|
|
31
|
-
}) {
|
|
32
|
-
if (!root) throw new Error("Root directory must be specified.");
|
|
33
|
-
if (!pagesDirectory) throw new Error("Pages directory must be specified.");
|
|
34
|
-
root = normalize(root).replace(/[\\/]+$/, "");
|
|
35
|
-
pagesDirectory = normalize(pagesDirectory).replace(/[\\/]+$/, "");
|
|
36
|
-
const requestHandler = async (req, res) => {
|
|
37
|
-
try {
|
|
38
|
-
if (!req.url) {
|
|
39
|
-
await sendResponse(req, res, 400, {
|
|
40
|
-
"Content-Type": "text/plain; charset=utf-8"
|
|
41
|
-
}, "Bad Request");
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
45
|
-
res.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
|
|
46
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
47
|
-
if (req.method === "OPTIONS") {
|
|
48
|
-
res.writeHead(204);
|
|
49
|
-
res.end();
|
|
50
|
-
if (environment === "development") {
|
|
51
|
-
log.info(req.method, "::", req.url, "-", res.statusCode);
|
|
52
|
-
}
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
56
|
-
if (url.pathname.startsWith("/api/")) {
|
|
57
|
-
await handleApiRequest(pagesDirectory, url.pathname, req, res);
|
|
58
|
-
} else if (doesPageExist(url.pathname)) {
|
|
59
|
-
await handlePageRequest(root, pagesDirectory, url.pathname, req, res, DIST_DIR, getPage(url.pathname));
|
|
60
|
-
} else {
|
|
61
|
-
await handleStaticRequest(root, pagesDirectory, url.pathname, req, res, DIST_DIR);
|
|
62
|
-
}
|
|
63
|
-
if (environment === "development") {
|
|
64
|
-
log.info(req.method, "::", req.url, "-", res.statusCode);
|
|
65
|
-
}
|
|
66
|
-
} catch (err) {
|
|
67
|
-
log.error(err);
|
|
68
|
-
await sendResponse(req, res, 500, {
|
|
69
|
-
"Content-Type": "text/plain; charset=utf-8"
|
|
70
|
-
}, "Internal Server Error");
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
function attemptListen(p) {
|
|
74
|
-
const server = createHttpServer(requestHandler);
|
|
75
|
-
server.on("error", (err) => {
|
|
76
|
-
if (err.code === "EADDRINUSE") {
|
|
77
|
-
attemptListen(p + 1);
|
|
78
|
-
} else {
|
|
79
|
-
console.error(err);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
server.listen(p, host, () => {
|
|
83
|
-
log.info(`Server running at http://${host}:${p}/`);
|
|
84
|
-
});
|
|
85
|
-
return server;
|
|
86
|
-
}
|
|
87
|
-
return attemptListen(port);
|
|
88
|
-
}
|
|
89
|
-
async function getTargetInfo(root, pathname) {
|
|
90
|
-
const originalPathname = pathname;
|
|
91
|
-
const filePath = normalize(join(root, decodeURIComponent(pathname))).replace(/[\\/]+$/, "");
|
|
92
|
-
if (!filePath.startsWith(root)) {
|
|
93
|
-
throw new Error("Forbidden");
|
|
94
|
-
}
|
|
95
|
-
let stats;
|
|
96
|
-
try {
|
|
97
|
-
stats = await fs.stat(filePath);
|
|
98
|
-
} catch {
|
|
99
|
-
}
|
|
100
|
-
let targetDir;
|
|
101
|
-
if (stats) {
|
|
102
|
-
targetDir = stats.isDirectory() ? filePath : dirname(filePath);
|
|
103
|
-
} else {
|
|
104
|
-
targetDir = originalPathname.endsWith("/") ? filePath : dirname(filePath);
|
|
105
|
-
}
|
|
106
|
-
return {
|
|
107
|
-
filePath,
|
|
108
|
-
targetDir,
|
|
109
|
-
stats
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
function getMiddlewareDirs(base, parts) {
|
|
113
|
-
const middlewareDirs = [];
|
|
114
|
-
let current = base;
|
|
115
|
-
middlewareDirs.push(current);
|
|
116
|
-
for (const part of parts) {
|
|
117
|
-
current = join(current, part);
|
|
118
|
-
middlewareDirs.push(current);
|
|
119
|
-
}
|
|
120
|
-
return middlewareDirs;
|
|
121
|
-
}
|
|
122
|
-
async function collectMiddlewares(dirs) {
|
|
123
|
-
const middlewares = [];
|
|
124
|
-
for (const dir of dirs) {
|
|
125
|
-
const mwPath = join(dir, "middleware.ts");
|
|
126
|
-
let mwModule;
|
|
127
|
-
try {
|
|
128
|
-
await fs.access(mwPath);
|
|
129
|
-
const url = pathToFileURL(mwPath).href;
|
|
130
|
-
mwModule = await import(url);
|
|
131
|
-
} catch {
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
const mwKeys = Object.keys(mwModule).sort();
|
|
135
|
-
for (const key of mwKeys) {
|
|
136
|
-
const f = mwModule[key];
|
|
137
|
-
if (typeof f === "function" && !middlewares.some((existing) => existing === f)) {
|
|
138
|
-
middlewares.push(f);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return middlewares;
|
|
143
|
-
}
|
|
144
|
-
async function handlePageRequest(root, pagesDirectory, pathname, req, res, DIST_DIR, pageInfo) {
|
|
145
|
-
try {
|
|
146
|
-
const {
|
|
147
|
-
filePath,
|
|
148
|
-
targetDir,
|
|
149
|
-
stats
|
|
150
|
-
} = await getTargetInfo(root, pathname);
|
|
151
|
-
const relDir = targetDir.slice(root.length).replace(/^[\/\\]+/, "");
|
|
152
|
-
const parts = relDir.split(/[\\/]/).filter(Boolean);
|
|
153
|
-
const middlewareDirs = getMiddlewareDirs(pagesDirectory, parts);
|
|
154
|
-
const middlewares = await collectMiddlewares(middlewareDirs);
|
|
155
|
-
const data = {};
|
|
156
|
-
const isDynamic = pageInfo.isDynamic;
|
|
157
|
-
const handlerPath = isDynamic ? pageInfo.filePath : join(filePath, "index.html");
|
|
158
|
-
let hasHandler = false;
|
|
159
|
-
try {
|
|
160
|
-
await fs.access(handlerPath);
|
|
161
|
-
hasHandler = true;
|
|
162
|
-
} catch {
|
|
163
|
-
}
|
|
164
|
-
const finalHandler = async (req2, res2) => {
|
|
165
|
-
if (!hasHandler) {
|
|
166
|
-
await respondWithErrorPage(root, pathname, 404, req2, res2);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (isDynamic) {
|
|
170
|
-
try {
|
|
171
|
-
const {
|
|
172
|
-
buildDynamicPage
|
|
173
|
-
} = await import("../compilation/dynamic_compiler");
|
|
174
|
-
const result = await buildDynamicPage(
|
|
175
|
-
DIST_DIR,
|
|
176
|
-
pathname,
|
|
177
|
-
pageInfo,
|
|
178
|
-
req2,
|
|
179
|
-
res2,
|
|
180
|
-
data
|
|
181
|
-
);
|
|
182
|
-
if (result === false) {
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
const {
|
|
186
|
-
resultHTML
|
|
187
|
-
} = result;
|
|
188
|
-
if (resultHTML === false) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
await sendResponse(req2, res2, 200, {
|
|
192
|
-
"Content-Type": MIME_TYPES[".html"]
|
|
193
|
-
}, resultHTML);
|
|
194
|
-
} catch (err) {
|
|
195
|
-
log.error("Error building dynamic page -", err);
|
|
196
|
-
}
|
|
197
|
-
} else {
|
|
198
|
-
const ext = extname(handlerPath).toLowerCase();
|
|
199
|
-
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
200
|
-
const fileData = await fs.readFile(handlerPath);
|
|
201
|
-
await sendResponse(req2, res2, 200, {
|
|
202
|
-
"Content-Type": contentType
|
|
203
|
-
}, fileData);
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
const composed = composeMiddlewares(middlewares, finalHandler, {
|
|
207
|
-
isApi: false,
|
|
208
|
-
root,
|
|
209
|
-
pathname,
|
|
210
|
-
data
|
|
211
|
-
});
|
|
212
|
-
await composed(req, res);
|
|
213
|
-
} catch (err) {
|
|
214
|
-
if (err.message === "Forbidden") {
|
|
215
|
-
await sendResponse(req, res, 403, {
|
|
216
|
-
"Content-Type": "text/plain; charset=utf-8"
|
|
217
|
-
}, "Forbidden");
|
|
218
|
-
} else {
|
|
219
|
-
throw err;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
async function handleStaticRequest(root, pagesDirectory, pathname, req, res, DIST_DIR) {
|
|
224
|
-
try {
|
|
225
|
-
const {
|
|
226
|
-
filePath,
|
|
227
|
-
targetDir,
|
|
228
|
-
stats
|
|
229
|
-
} = await getTargetInfo(root, pathname);
|
|
230
|
-
const relDir = targetDir.slice(root.length).replace(/^[\/\\]+/, "");
|
|
231
|
-
const parts = relDir.split(/[\\/]/).filter(Boolean);
|
|
232
|
-
const middlewareDirs = getMiddlewareDirs(pagesDirectory, parts);
|
|
233
|
-
const middlewares = await collectMiddlewares(middlewareDirs);
|
|
234
|
-
let handlerPath = filePath;
|
|
235
|
-
if (stats && stats.isDirectory()) {
|
|
236
|
-
handlerPath = join(filePath, "index.html");
|
|
237
|
-
}
|
|
238
|
-
let hasHandler = false;
|
|
239
|
-
try {
|
|
240
|
-
await fs.access(handlerPath);
|
|
241
|
-
hasHandler = true;
|
|
242
|
-
} catch {
|
|
243
|
-
}
|
|
244
|
-
const finalHandler = async (req2, res2) => {
|
|
245
|
-
if (!hasHandler) {
|
|
246
|
-
await respondWithErrorPage(root, pathname, 404, req2, res2);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
const ext = extname(handlerPath).toLowerCase();
|
|
250
|
-
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
251
|
-
const fileData = await fs.readFile(handlerPath);
|
|
252
|
-
await sendResponse(req2, res2, 200, {
|
|
253
|
-
"Content-Type": contentType
|
|
254
|
-
}, fileData);
|
|
255
|
-
};
|
|
256
|
-
const composed = composeMiddlewares(middlewares, finalHandler, {
|
|
257
|
-
isApi: false,
|
|
258
|
-
root,
|
|
259
|
-
pathname
|
|
260
|
-
});
|
|
261
|
-
await composed(req, res);
|
|
262
|
-
} catch (err) {
|
|
263
|
-
if (err.message === "Forbidden") {
|
|
264
|
-
await sendResponse(req, res, 403, {
|
|
265
|
-
"Content-Type": "text/plain; charset=utf-8"
|
|
266
|
-
}, "Forbidden");
|
|
267
|
-
} else {
|
|
268
|
-
throw err;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
async function handleApiRequest(pagesDirectory, pathname, req, res) {
|
|
273
|
-
const apiSubPath = pathname.slice("/api/".length);
|
|
274
|
-
const parts = apiSubPath.split("/").filter(Boolean);
|
|
275
|
-
const middlewareDirs = getMiddlewareDirs(join(pagesDirectory, "api"), parts);
|
|
276
|
-
const middlewares = await collectMiddlewares(middlewareDirs);
|
|
277
|
-
const routeDir = middlewareDirs[middlewareDirs.length - 1];
|
|
278
|
-
const routePath = join(routeDir, "route.ts");
|
|
279
|
-
let hasRoute = false;
|
|
280
|
-
try {
|
|
281
|
-
await fs.access(routePath);
|
|
282
|
-
hasRoute = true;
|
|
283
|
-
} catch {
|
|
284
|
-
}
|
|
285
|
-
let fn = null;
|
|
286
|
-
let module = null;
|
|
287
|
-
if (hasRoute) {
|
|
288
|
-
try {
|
|
289
|
-
const moduleUrl = pathToFileURL(routePath).href;
|
|
290
|
-
module = await import(moduleUrl);
|
|
291
|
-
fn = module[req.method];
|
|
292
|
-
} catch (err) {
|
|
293
|
-
console.error(err);
|
|
294
|
-
return respondWithJsonError(req, res, 500, "Internal Server Error");
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
const finalHandler = async (req2, res2) => {
|
|
298
|
-
if (!hasRoute) {
|
|
299
|
-
return respondWithJsonError(req2, res2, 404, "Not Found");
|
|
300
|
-
}
|
|
301
|
-
if (typeof fn !== "function") {
|
|
302
|
-
return respondWithJsonError(req2, res2, 405, "Method Not Allowed");
|
|
303
|
-
}
|
|
304
|
-
await fn(req2, res2);
|
|
305
|
-
};
|
|
306
|
-
const composed = composeMiddlewares(middlewares, finalHandler, {
|
|
307
|
-
isApi: true
|
|
308
|
-
});
|
|
309
|
-
await composed(req, res);
|
|
310
|
-
}
|
|
311
|
-
function composeMiddlewares(mws, final, options) {
|
|
312
|
-
return async function(req, res) {
|
|
313
|
-
let index = 0;
|
|
314
|
-
async function dispatch(err) {
|
|
315
|
-
if (err) {
|
|
316
|
-
if (options.isApi) {
|
|
317
|
-
return respondWithJsonError(req, res, 500, err.message || "Internal Server Error");
|
|
318
|
-
} else {
|
|
319
|
-
return await respondWithErrorPage(options.root, options.pathname, 500, req, res);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
if (index >= mws.length) {
|
|
323
|
-
return await final(req, res);
|
|
324
|
-
}
|
|
325
|
-
const thisMw = mws[index++];
|
|
326
|
-
const next = (e) => dispatch(e);
|
|
327
|
-
const onceNext = (nextFn) => {
|
|
328
|
-
let called = false;
|
|
329
|
-
return async (e) => {
|
|
330
|
-
if (called) {
|
|
331
|
-
log.warn("next() was called in a middleware more than once.");
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
called = true;
|
|
335
|
-
await nextFn(e);
|
|
336
|
-
};
|
|
337
|
-
};
|
|
338
|
-
try {
|
|
339
|
-
await thisMw(req, res, onceNext(next), options.data || {});
|
|
340
|
-
} catch (error) {
|
|
341
|
-
await dispatch(error);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
await dispatch();
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
async function respondWithJsonError(req, res, code, message) {
|
|
348
|
-
const body = JSON.stringify({
|
|
349
|
-
error: message
|
|
350
|
-
});
|
|
351
|
-
await sendResponse(req, res, code, {
|
|
352
|
-
"Content-Type": "application/json; charset=utf-8"
|
|
353
|
-
}, body);
|
|
354
|
-
}
|
|
355
|
-
async function respondWithErrorPage(root, pathname, code, req, res) {
|
|
356
|
-
let currentPath = normalize(join(root, decodeURIComponent(pathname)));
|
|
357
|
-
let tried = /* @__PURE__ */ new Set();
|
|
358
|
-
let errorFilePath = null;
|
|
359
|
-
while (currentPath.startsWith(root)) {
|
|
360
|
-
const candidate = join(currentPath, `${code}.html`);
|
|
361
|
-
if (!tried.has(candidate)) {
|
|
362
|
-
try {
|
|
363
|
-
await fs.access(candidate);
|
|
364
|
-
errorFilePath = candidate;
|
|
365
|
-
break;
|
|
366
|
-
} catch {
|
|
367
|
-
}
|
|
368
|
-
tried.add(candidate);
|
|
369
|
-
}
|
|
370
|
-
const parent = dirname(currentPath);
|
|
371
|
-
if (parent === currentPath) break;
|
|
372
|
-
currentPath = parent;
|
|
373
|
-
}
|
|
374
|
-
if (!errorFilePath) {
|
|
375
|
-
const fallback = join(root, `${code}.html`);
|
|
376
|
-
try {
|
|
377
|
-
await fs.access(fallback);
|
|
378
|
-
errorFilePath = fallback;
|
|
379
|
-
} catch {
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
if (errorFilePath) {
|
|
383
|
-
try {
|
|
384
|
-
const html = await fs.readFile(errorFilePath, "utf8");
|
|
385
|
-
await sendResponse(req, res, code, {
|
|
386
|
-
"Content-Type": "text/html; charset=utf-8"
|
|
387
|
-
}, html);
|
|
388
|
-
return;
|
|
389
|
-
} catch {
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
await sendResponse(req, res, code, {
|
|
393
|
-
"Content-Type": "text/plain; charset=utf-8"
|
|
394
|
-
}, `${code} Error`);
|
|
395
|
-
}
|
|
396
|
-
function isCompressible(contentType) {
|
|
397
|
-
if (!contentType) return false;
|
|
398
|
-
return /text\/|javascript|json|xml|svg/.test(contentType);
|
|
399
|
-
}
|
|
400
|
-
async function sendResponse(req, res, status, headers, body) {
|
|
401
|
-
let bufferBody = typeof body === "string" ? Buffer.from(body) : body;
|
|
402
|
-
const accept = req.headers["accept-encoding"] || "";
|
|
403
|
-
let encoding = null;
|
|
404
|
-
if (accept.match(/\bgzip\b/)) {
|
|
405
|
-
encoding = "gzip";
|
|
406
|
-
} else if (accept.match(/\bdeflate\b/)) {
|
|
407
|
-
encoding = "deflate";
|
|
408
|
-
}
|
|
409
|
-
if (!encoding || !isCompressible(headers["Content-Type"] || "")) {
|
|
410
|
-
res.writeHead(status, headers);
|
|
411
|
-
res.end(bufferBody);
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
const compressor = encoding === "gzip" ? gzipAsync : deflateAsync;
|
|
415
|
-
try {
|
|
416
|
-
const compressed = await compressor(bufferBody);
|
|
417
|
-
headers["Content-Encoding"] = encoding;
|
|
418
|
-
headers["Vary"] = "Accept-Encoding";
|
|
419
|
-
res.writeHead(status, headers);
|
|
420
|
-
res.end(compressed);
|
|
421
|
-
} catch (err) {
|
|
422
|
-
log.error("Compression error:", err);
|
|
423
|
-
res.writeHead(status, headers);
|
|
424
|
-
res.end(bufferBody);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
export {
|
|
428
|
-
startServer
|
|
429
|
-
};
|
package/dist/server/state.d.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { ObjectAttributeType } from "../helpers/ObjectAttributeType";
|
|
2
|
-
type ClientSubjectGeneric<T> = Omit<ClientSubject, "value"> & {
|
|
3
|
-
value: T;
|
|
4
|
-
};
|
|
5
|
-
type Widen<T> = T extends number ? number : T extends string ? string : T extends boolean ? boolean : T extends {} ? T & Record<string, any> : T;
|
|
6
|
-
export declare const state: <U extends number | string | boolean | {} | undefined | null | Array<any>>(value: U, options?: {
|
|
7
|
-
isGlobal: boolean;
|
|
8
|
-
}) => {
|
|
9
|
-
id: number;
|
|
10
|
-
value: Widen<U>;
|
|
11
|
-
type: ObjectAttributeType.STATE;
|
|
12
|
-
bind: string | undefined;
|
|
13
|
-
reactiveMap: U extends Array<any> ? ReactiveMap<U, any> : null;
|
|
14
|
-
};
|
|
15
|
-
type ReactiveMap<T extends any[], D extends Dependencies> = (this: {
|
|
16
|
-
id: number;
|
|
17
|
-
value: any;
|
|
18
|
-
type: ObjectAttributeType.STATE;
|
|
19
|
-
bind: string | undefined;
|
|
20
|
-
}, template: (item: T[number], index: number, ...deps: {
|
|
21
|
-
[K in keyof D]: ClientSubjectGeneric<D[K]>["value"];
|
|
22
|
-
}) => Child, deps?: [...D]) => Child;
|
|
23
|
-
type Dependencies = {
|
|
24
|
-
type: ObjectAttributeType;
|
|
25
|
-
value: unknown;
|
|
26
|
-
id: number;
|
|
27
|
-
bind?: string;
|
|
28
|
-
}[];
|
|
29
|
-
export type SetEvent<Event, Target> = Omit<Event, "currentTarget"> & {
|
|
30
|
-
currentTarget: Target;
|
|
31
|
-
};
|
|
32
|
-
export declare const eventListener: <D extends Dependencies, E extends Event, T>(dependencies: [...D] | [], eventListener: (event: SetEvent<E, T>, ...subjects: { [K in keyof D]: ClientSubjectGeneric<D[K]["value"]>; }) => void) => {
|
|
33
|
-
id: number;
|
|
34
|
-
type: ObjectAttributeType;
|
|
35
|
-
value: Function;
|
|
36
|
-
};
|
|
37
|
-
export declare const initializeState: () => never[];
|
|
38
|
-
export declare const getState: () => {
|
|
39
|
-
value: unknown;
|
|
40
|
-
type: ObjectAttributeType;
|
|
41
|
-
id: number;
|
|
42
|
-
bind?: number;
|
|
43
|
-
}[];
|
|
44
|
-
export declare const initializeObjectAttributes: () => never[];
|
|
45
|
-
export declare const getObjectAttributes: () => ({
|
|
46
|
-
type: ObjectAttributeType;
|
|
47
|
-
id: string | number;
|
|
48
|
-
value: any;
|
|
49
|
-
bind?: string;
|
|
50
|
-
} | {
|
|
51
|
-
type: ObjectAttributeType;
|
|
52
|
-
refs: {
|
|
53
|
-
id: number;
|
|
54
|
-
bind?: string;
|
|
55
|
-
}[];
|
|
56
|
-
initialValues: any[];
|
|
57
|
-
update: (...value: any) => any;
|
|
58
|
-
} | {
|
|
59
|
-
type: ObjectAttributeType;
|
|
60
|
-
})[];
|
|
61
|
-
export {};
|
package/dist/server/state.mjs
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { ObjectAttributeType } from "../helpers/ObjectAttributeType";
|
|
2
|
-
import { loadHook } from "./loadHook";
|
|
3
|
-
if (!globalThis.__SERVER_CURRENT_STATE_ID__) {
|
|
4
|
-
globalThis.__SERVER_CURRENT_STATE_ID__ = 1;
|
|
5
|
-
}
|
|
6
|
-
const state = (value, options) => {
|
|
7
|
-
const serverStateEntry = {
|
|
8
|
-
id: __SERVER_CURRENT_STATE_ID__ += 1,
|
|
9
|
-
value,
|
|
10
|
-
type: ObjectAttributeType.STATE
|
|
11
|
-
};
|
|
12
|
-
globalThis.__SERVER_CURRENT_STATE__.push(serverStateEntry);
|
|
13
|
-
if (Array.isArray(value)) {
|
|
14
|
-
serverStateEntry.reactiveMap = reactiveMap;
|
|
15
|
-
}
|
|
16
|
-
return serverStateEntry;
|
|
17
|
-
};
|
|
18
|
-
const reactiveMap = function(template, deps) {
|
|
19
|
-
const subject = this;
|
|
20
|
-
const dependencies = state(deps || []);
|
|
21
|
-
const templateFn = state(template);
|
|
22
|
-
loadHook(
|
|
23
|
-
[subject, templateFn, dependencies],
|
|
24
|
-
(state2, subject2, templateFn2, dependencies2) => {
|
|
25
|
-
const el = document.querySelector(
|
|
26
|
-
`[map-id="${subject2.id}"]`
|
|
27
|
-
);
|
|
28
|
-
if (!el) {
|
|
29
|
-
console.error(`Couldn't find map tag with map-id=${subject2.id}`);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const parentElement = el.parentElement;
|
|
33
|
-
const nextSibling = el.nextSibling;
|
|
34
|
-
el.remove();
|
|
35
|
-
const value = subject2.value;
|
|
36
|
-
const deps2 = state2.getAll(dependencies2.value.map((dep) => ({ id: dep.id, bind: dep.bind })));
|
|
37
|
-
const attributes = [];
|
|
38
|
-
const currentlyWatched = [];
|
|
39
|
-
const createElements = () => {
|
|
40
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
41
|
-
const htmlElement = client.renderRecursively(templateFn2.value(value[i], i, ...deps2), attributes);
|
|
42
|
-
htmlElement.setAttribute("map-id", subject2.id.toString());
|
|
43
|
-
const elementKey = ((i - 1) * -1).toString();
|
|
44
|
-
htmlElement.setAttribute("key", elementKey);
|
|
45
|
-
for (const attribute of attributes) {
|
|
46
|
-
let values = {};
|
|
47
|
-
const type = attribute.type;
|
|
48
|
-
switch (type) {
|
|
49
|
-
case ObjectAttributeType.OBSERVER: {
|
|
50
|
-
const { field, subjects, updateCallback } = attribute;
|
|
51
|
-
for (const reference of subjects) {
|
|
52
|
-
const subject3 = state2.get(reference.id, reference.bind);
|
|
53
|
-
const updateFunction = (value2) => {
|
|
54
|
-
values[subject3.id] = value2;
|
|
55
|
-
try {
|
|
56
|
-
const newValue = updateCallback(...Object.values(values));
|
|
57
|
-
let attribute2 = field === "class" ? "className" : field;
|
|
58
|
-
htmlElement[attribute2] = newValue;
|
|
59
|
-
} catch (e) {
|
|
60
|
-
console.error(e);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
updateFunction(subject3.value);
|
|
65
|
-
state2.observe(subject3, updateFunction, elementKey);
|
|
66
|
-
currentlyWatched.push({
|
|
67
|
-
key: elementKey,
|
|
68
|
-
subject: subject3
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
73
|
-
case ObjectAttributeType.STATE: {
|
|
74
|
-
const { field, element, subjects, eventListener: eventListener2 } = attribute;
|
|
75
|
-
const lc = field.toLowerCase();
|
|
76
|
-
const fn = (event) => {
|
|
77
|
-
eventListener2(event, ...subjects);
|
|
78
|
-
};
|
|
79
|
-
element[lc] = fn;
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
parentElement.insertBefore(htmlElement, nextSibling);
|
|
85
|
-
attributes.splice(0, attributes.length);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
const removeOldElements = () => {
|
|
89
|
-
const list = Array.from(document.querySelectorAll(`[map-id="${subject2.id}"]`));
|
|
90
|
-
for (const el2 of list) {
|
|
91
|
-
el2.remove();
|
|
92
|
-
}
|
|
93
|
-
for (const watched of currentlyWatched) {
|
|
94
|
-
state2.unobserve(watched.subject, watched.key);
|
|
95
|
-
}
|
|
96
|
-
currentlyWatched.splice(0, currentlyWatched.length);
|
|
97
|
-
};
|
|
98
|
-
createElements();
|
|
99
|
-
const uniqueId = `${Date.now()}`;
|
|
100
|
-
state2.observe(subject2, (value2) => {
|
|
101
|
-
removeOldElements();
|
|
102
|
-
createElements();
|
|
103
|
-
}, uniqueId);
|
|
104
|
-
}
|
|
105
|
-
);
|
|
106
|
-
return globalThis.template({
|
|
107
|
-
"map-id": subject.id
|
|
108
|
-
});
|
|
109
|
-
};
|
|
110
|
-
const eventListener = (dependencies, eventListener2) => {
|
|
111
|
-
const deps = dependencies.map((dep) => ({ id: dep.id, bind: dep.bind }));
|
|
112
|
-
let dependencyString = "[";
|
|
113
|
-
for (const dep of deps) {
|
|
114
|
-
dependencyString += `{id:${dep.id}`;
|
|
115
|
-
if (dep.bind) dependencyString += `,bind:${dep.bind}`;
|
|
116
|
-
dependencyString += `},`;
|
|
117
|
-
}
|
|
118
|
-
dependencyString += "]";
|
|
119
|
-
const value = {
|
|
120
|
-
id: __SERVER_CURRENT_STATE_ID__ += 1,
|
|
121
|
-
type: ObjectAttributeType.STATE,
|
|
122
|
-
value: new Function(
|
|
123
|
-
"state",
|
|
124
|
-
"event",
|
|
125
|
-
`(${eventListener2.toString()})(event, ...state.getAll(${dependencyString}))`
|
|
126
|
-
)
|
|
127
|
-
};
|
|
128
|
-
globalThis.__SERVER_CURRENT_STATE__.push(value);
|
|
129
|
-
return value;
|
|
130
|
-
};
|
|
131
|
-
const initializeState = () => globalThis.__SERVER_CURRENT_STATE__ = [];
|
|
132
|
-
const getState = () => {
|
|
133
|
-
return globalThis.__SERVER_CURRENT_STATE__;
|
|
134
|
-
};
|
|
135
|
-
const initializeObjectAttributes = () => globalThis.__SERVER_CURRENT_OBJECT_ATTRIBUTES__ = [];
|
|
136
|
-
const getObjectAttributes = () => {
|
|
137
|
-
return globalThis.__SERVER_CURRENT_OBJECT_ATTRIBUTES__;
|
|
138
|
-
};
|
|
139
|
-
export {
|
|
140
|
-
eventListener,
|
|
141
|
-
getObjectAttributes,
|
|
142
|
-
getState,
|
|
143
|
-
initializeObjectAttributes,
|
|
144
|
-
initializeState,
|
|
145
|
-
state
|
|
146
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
declare const createElementOptions: (obj: Record<string, any>) => () => Record<string, any>;
|
|
2
|
-
declare const elements: {
|
|
3
|
-
[key: string]: EleganceElement<ElementTags>;
|
|
4
|
-
};
|
|
5
|
-
declare const childrenlessElements: {
|
|
6
|
-
[key: string]: EleganceChildrenlessElement<ChildrenlessElementTags>;
|
|
7
|
-
};
|
|
8
|
-
declare const allElements: {
|
|
9
|
-
[x: string]: EleganceElement<ElementTags> | EleganceChildrenlessElement<ChildrenlessElementTags>;
|
|
10
|
-
};
|
|
11
|
-
export { elements, childrenlessElements, createElementOptions, allElements };
|